home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Graphics / Multimedia / Movie3.0 / Source / xanim / xanim_iff.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-02  |  77.5 KB  |  2,672 lines

  1.  
  2. /*
  3.  * xanim_iff.c
  4.  *
  5.  * Copyright (C) 1990,1991,1992,1993,1994 by Mark Podlipec. 
  6.  * All rights reserved.
  7.  *
  8.  * This software may be freely copied, modified and redistributed without
  9.  * fee for non-commerical purposes provided that this copyright notice is
  10.  * preserved intact on all copies and modified copies.
  11.  * 
  12.  * There is no warranty or other guarantee of fitness of this software.
  13.  * It is provided solely "as is". The author(s) disclaim(s) all
  14.  * responsibility and liability with respect to this software's usage
  15.  * or its effect upon hardware or computer systems.
  16.  *
  17.  */
  18. #include "xanim.h"
  19. #include "xanim_iff.h"
  20.  
  21. ULONG IFF_Read_File();
  22. void IFF_Adjust_For_EHB();
  23. void IFF_Read_BODY();
  24. LONG IFF_Read_Garb();
  25. void IFF_Print_ID();
  26. ULONG IFF_Delta_Body();
  27. ULONG IFF_Delta_l();
  28. ULONG IFF_Delta_3();
  29. ULONG IFF_Delta_5();
  30. ULONG IFF_Delta_7();
  31. ULONG IFF_Delta_J();
  32. void IFF_Long_Mod();
  33. LONG Is_IFF_File();
  34. void IFF_Buffer_Action();
  35. void IFF_Buffer_HAM6();
  36. void IFF_Buffer_HAM8();
  37. void IFF_Setup_HMAP();
  38. void IFF_Setup_CMAP();
  39. IFF_ACT_LST *IFF_Add_Frame();
  40. void IFF_Image_To_Bufferable();
  41. void IFF_Read_BMHD();
  42. void IFF_Read_ANHD();
  43. void IFF_Read_ANSQ();
  44. void IFF_Register_CRNGs();
  45. void IFF_Read_CRNG();
  46. void IFF_Read_CMAP_0();
  47. void IFF_Read_CMAP_1();
  48. void IFF_Init_DLTA_HDR();
  49. void IFF_Update_DLTA_HDR();
  50. void IFF_Free_Stuff();
  51. void IFF_Shift_CMAP();
  52. void IFF_HAM6_As_True();
  53. void IFF_HAM8_As_True();
  54. void IFF_Hash_CleanUp();
  55. void IFF_Hash_Init();
  56. void IFF_Hash_Add();
  57. XA_ACTION *IFF_Hash_Get();
  58. ULONG IFF_Check_Same();
  59.  
  60.  
  61. ULONG UTIL_Get_MSB_Long();
  62. LONG UTIL_Get_MSB_Short();
  63. ULONG UTIL_Get_MSB_UShort();
  64. ULONG CMAP_Get_Or_Mask();
  65. XA_CHDR *CMAP_Create_332();
  66. XA_CHDR *CMAP_Create_Gray();
  67. XA_CHDR *CMAP_Create_CHDR_From_True();
  68. void ACT_Add_CHDR_To_Action();
  69. void ACT_Del_CHDR_From_Action();
  70. void UTIL_Mapped_To_Bitmap();
  71. void UTIL_Mapped_To_Mapped();
  72. UBYTE *UTIL_RGB_To_Map();
  73. UBYTE *UTIL_RGB_To_FS_Map();
  74. void ACT_Free_Act();
  75. ULONG UTIL_Get_Buffer_Scale();
  76. void UTIL_Scale_Pos_Size();
  77.  
  78. extern LONG xa_anim_cycling;
  79.  
  80. XA_ACTION *ACT_Get_Action();
  81. void ACT_Setup_Mapped();
  82. void UTIL_Sub_Image();
  83. XA_CHDR *ACT_Get_CMAP();
  84.  
  85. #define IFF_SPEED_DEFAULT 3
  86. #define ACT_IFF_HMAP6 0x2000
  87. #define ACT_IFF_HMAP8 0x2001
  88.  
  89. typedef struct
  90. {
  91.   ULONG flag;
  92.   XA_ACTION *dlta;
  93.   XA_ACTION *src;
  94.   XA_ACTION *dst;
  95.   XA_ACTION *nxtdlta;
  96. } IFF_HASH;
  97.  
  98. IFF_HASH *iff_hash_tbl;
  99. ULONG iff_hash_cur = 0;
  100.  
  101.  
  102. static IFF_ANSQ *iff_ansq;
  103. static ULONG iff_ansq_cnt;
  104. static IFF_DLTA_TABLE *iff_dlta_acts;
  105.  
  106. static LONG  iff_allow_cycling;
  107. static ULONG iff_time;
  108. static ULONG iff_anim_flags;
  109. static ULONG iff_cmap_bits;
  110. static ColorReg iff_hmap[XA_HMAP_SIZE];
  111. static ColorReg *iff_cur_hmap;
  112. static ColorReg iff_cmap[256];
  113. static XA_CHDR *iff_chdr;
  114.  
  115. static LONG mask[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
  116.  
  117. static IFF_ACT_LST *iff_act_start,*iff_act_cur;
  118. static ULONG iff_act_cnt;
  119. static ULONG iff_dlta_cnt;
  120. static ULONG iff_dlta_compression,iff_dlta_bits;
  121.  
  122. static ULONG iff_imagex,iff_imagey,iff_imagec,iff_imaged;
  123. static ULONG iff_max_imagex,iff_max_imagey,iff_max_imagec,iff_max_imaged;
  124. static ULONG iff_or_mask;
  125. static ULONG iff_max_fsize;
  126.  
  127. extern ULONG xa_ham_map_size;
  128. extern ULONG *xa_ham_map;
  129. extern XA_CHDR *xa_ham_chdr;
  130. extern ULONG xa_ham_init;
  131.  
  132. /*
  133.  * NOTES: the iff_cmap is read in as 8 bits. It's shifted down to 4 bits
  134.  * before ACT_GET_CMAP is called(unless there are 8 bit planes)
  135.  * How does one know whether is 4 bits or 8 bits per color component?
  136.  */
  137.  
  138. void
  139. IFF_TheEnd()
  140. {
  141.   IFF_Free_Stuff();
  142.   TheEnd();
  143. }
  144.  
  145. void
  146. IFF_TheEnd1(p)
  147. char *p;
  148. {
  149.   IFF_Free_Stuff();
  150.   TheEnd1(p);
  151. }
  152.  
  153. IFF_ACT_LST *IFF_Add_Frame(type,act)
  154. ULONG type;
  155. XA_ACTION *act;
  156. {
  157.   IFF_ACT_LST *iframe;
  158.  
  159.   iframe = (IFF_ACT_LST *) malloc(sizeof(IFF_ACT_LST));
  160.   if (iframe == 0) IFF_TheEnd1("IFF_Add_Frame: malloc err");
  161.  
  162.   if (type == 1) iff_dlta_cnt++;
  163.   iframe->type = type;
  164.   iframe->act = act;
  165.   iframe->next = 0;
  166.  
  167.   if (iff_act_start == 0) iff_act_start = iframe;
  168.   else iff_act_cur->next = iframe;
  169.  
  170.   iff_act_cur = iframe;
  171.   iff_act_cnt++;
  172.   return(iframe);
  173. }
  174.  
  175. void
  176. IFF_Free_Stuff()
  177. {
  178.   IFF_ACT_LST *itmp;
  179.  
  180.   if (iff_ansq) FREE(iff_ansq,0x1000);
  181.   if (iff_dlta_acts) FREE(iff_dlta_acts,0x1001); 
  182.   iff_ansq = 0; iff_dlta_acts = 0;
  183.   while(iff_act_start != 0)
  184.   {
  185.     itmp = iff_act_start;
  186.     iff_act_start = iff_act_start->next;
  187.     FREE(itmp,0x1003);
  188.   }
  189.   iff_ansq = 0;
  190.   iff_dlta_acts = 0;
  191.   iff_act_start = 0;
  192. }
  193.  
  194.  
  195. /*
  196.  *
  197.  */
  198. ULONG IFF_Read_File(fname,anim_hdr)
  199. BYTE *fname;
  200. XA_ANIM_HDR *anim_hdr;
  201. {
  202.   FILE *fin;
  203.   LONG camg_flag,cmap_flag,chdr_flag,ret;
  204.   LONG crng_flag,formtype;
  205.   LONG ansq_flag;
  206.   LONG face_flag,bmhd_flag,file_size,file_read;
  207.   Bit_Map_Header bmhd;
  208.   Chunk_Header  chunk;
  209.   LONG prop_flag;
  210.   LONG exit_flag;
  211.  
  212.  
  213.   iff_allow_cycling = (anim_hdr->anim_flags & ANIM_CYCLE)?(TRUE):(FALSE);
  214.   iff_act_start    = 0;
  215.   iff_act_cur    = 0;
  216.   iff_act_cnt    = 0;
  217.   iff_dlta_compression = 0xffff;
  218.   iff_dlta_bits = 0;
  219.   iff_anim_flags = anim_hdr->anim_flags & ~(ANIM_LACE | ANIM_HAM | ANIM_CYCLE);
  220.   file_size    = 0;
  221.   file_read    = 0;
  222.   iff_imagex = iff_max_imagex = 0;
  223.   iff_imagey = iff_max_imagey = 0;
  224.   iff_imagec = iff_max_imagec = 0;
  225.   iff_imaged = iff_max_imaged = 0;
  226.   iff_or_mask = 0;
  227.   iff_max_fsize = 0;
  228.   prop_flag    = 0;
  229.   bmhd_flag    = 0;
  230.   face_flag    = 0;
  231.   crng_flag    = 0;
  232.   camg_flag    = 0;
  233.   cmap_flag    = FALSE;
  234.   chdr_flag    = FALSE;
  235.   ansq_flag    = 0;
  236.   iff_ansq    = 0;
  237.   iff_ansq_cnt    = 0;
  238.   iff_dlta_acts    = 0;
  239.   iff_dlta_cnt    = 0;
  240.   iff_chdr    = 0;
  241.   iff_cmap_bits = 4;
  242.   iff_cur_hmap  = 0;
  243.  
  244.   if ( (fin=fopen(fname,XA_OPEN_MODE)) == 0)
  245.   { 
  246.     fprintf(stderr,"can't open %s\n",fname); 
  247.     return(FALSE);
  248.   }
  249.  
  250.   exit_flag = 0; 
  251.   while( !feof(fin) && !exit_flag)
  252.   {
  253.     /* read Chunk_Header 
  254.     */
  255.     chunk.id   = UTIL_Get_MSB_Long(fin);
  256.     chunk.size = UTIL_Get_MSB_Long(fin);
  257.  
  258.     if ( feof(fin) ) break;    
  259.     if (chunk.size == -1) ret = -1;
  260.     else ret = 0;
  261.  
  262.     DEBUG_LEVEL1
  263.     {
  264.       fprintf(stderr,"Chunk.ID = ");
  265.       IFF_Print_ID(stderr,chunk.id);
  266.       fprintf(stderr,"  chunksize=%lx\n",chunk.size);
  267.     }
  268.     if (chunk.size & 1) chunk.size+=1; /* halfword pad it */
  269.     if (ret==0)
  270.     {
  271.       switch(chunk.id)
  272.       {
  273.         case PROP: 
  274.                 prop_flag=1;
  275.         case LIST: 
  276.         case FORM: 
  277.                 formtype = UTIL_Get_MSB_Long(fin);
  278.         file_size = chunk.size;
  279.         file_read = -1;
  280.                 DEBUG_LEVEL2
  281.                 {
  282.                   fprintf(stderr,"  IFF ");
  283.                   IFF_Print_ID(stderr,chunk.id);
  284.                   fprintf(stderr," = ");
  285.                   IFF_Print_ID(stderr,formtype);
  286.                   fprintf(stderr,"\n");
  287.                 }
  288.                 break;
  289.         case BMHD:
  290.         IFF_Read_BMHD(fin,&bmhd);
  291.                 if (xa_verbose)
  292.                 {
  293.                  fprintf(stderr,"     Size %ldx%ldx%ld comp=%ld masking=%ld\n",
  294.                                 bmhd.width,bmhd.height,bmhd.depth,
  295.                                 bmhd.compression,bmhd.masking);
  296.                 }
  297.                 iff_imagex = bmhd.width;
  298.                 iff_imagey = bmhd.height;
  299.                 iff_imaged = bmhd.depth;
  300.         if (iff_imaged == 8) iff_cmap_bits = 8;
  301.         else iff_cmap_bits = 4;
  302.                 if (iff_imagex > iff_max_imagex) iff_max_imagex = iff_imagex;
  303.                 if (iff_imagey > iff_max_imagey) iff_max_imagey = iff_imagey;
  304.                 if (iff_imaged > iff_max_imaged) iff_max_imaged = iff_imaged;
  305.         /* or_mask is used to move pixels to upper reaches of cmap
  306.          */
  307.         iff_or_mask = CMAP_Get_Or_Mask(1 << iff_imaged);
  308.                 bmhd_flag = 1;
  309.                 break;
  310.  
  311.     case FACE: /* used in MovieSetter anims */
  312.           {
  313.         ULONG garb;
  314.         bmhd.pageWidth  = bmhd.width  = UTIL_Get_MSB_Short(fin);
  315.         bmhd.pageHeight = bmhd.height = UTIL_Get_MSB_Short(fin);
  316.         garb = UTIL_Get_MSB_Long(fin); /* read x, y */
  317.         garb = UTIL_Get_MSB_Long(fin); /* read xoff, yoff */
  318.         bmhd.depth = 5;
  319.         bmhd.compression = BMHD_COMP_BYTERUN;
  320.         bmhd.x = bmhd.y = bmhd.masking = 0;
  321.         bmhd.transparentColor = 0;
  322.         bmhd.xAspect = bmhd.yAspect = 0;
  323.                 face_flag = bmhd_flag = 1;
  324.                 iff_imagex = bmhd.width;
  325.                 iff_imagey = bmhd.height;
  326.                 iff_imaged = bmhd.depth;
  327.                 if (iff_imagex > iff_max_imagex) iff_max_imagex = iff_imagex;
  328.                 if (iff_imagey > iff_max_imagey) iff_max_imagey = iff_imagey;
  329.                 if (iff_imaged > iff_max_imaged) iff_max_imaged = iff_imaged;
  330.         iff_or_mask = CMAP_Get_Or_Mask(1 << iff_imaged);
  331.                 if (xa_verbose)
  332.                 {
  333.                  fprintf(stderr,"     Size %ldx%ldx%ld comp=%ld masking=%ld\n",
  334.                                 bmhd.width,bmhd.height,bmhd.depth,
  335.                                 bmhd.compression,bmhd.masking);
  336.                 }
  337.           }
  338.               break;
  339.  
  340.         case CAMG:
  341.                 {
  342.                   DEBUG_LEVEL2 fprintf(stderr,"IFF CAMG\n");
  343.                   if (chunk.size != 4) 
  344.                   {
  345.                     ret = IFF_Read_Garb(fin,chunk.size);
  346.                     break;
  347.                   }
  348.  
  349.                   camg_flag = UTIL_Get_MSB_Long(fin) | IFF_CAMG_NOP;
  350.  
  351.                   if ((camg_flag & IFF_CAMG_EHB) && (cmap_flag == TRUE))  
  352.                   {
  353.                     IFF_Adjust_For_EHB(iff_cmap,iff_cmap_bits);
  354.             iff_chdr = 
  355.             ACT_Get_CMAP(iff_cmap,iff_imagec,iff_or_mask,
  356.                 iff_imagec,iff_or_mask,
  357.                 iff_cmap_bits,iff_cmap_bits,iff_cmap_bits);
  358.             chdr_flag = TRUE;
  359.                     break;
  360.                   }
  361.                   if (camg_flag & IFF_CAMG_LACE) iff_anim_flags |= ANIM_LACE;
  362.  
  363.                   if ((camg_flag & IFF_CAMG_HAM) && (cmap_flag == TRUE)) 
  364.                   {
  365.                     XA_ACTION *act;
  366.  
  367.                         /* CREATE ACT_IFF_HMAP chunk */
  368.                     if (iff_cmap_bits == 8)
  369.                     {
  370.                       act = ACT_Get_Action(anim_hdr,ACT_IFF_HMAP8);
  371.                       iff_anim_flags |= ANIM_HAM8;
  372.                     }
  373.                     else
  374.                     {
  375.                       act = ACT_Get_Action(anim_hdr,ACT_IFF_HMAP6);
  376.                       iff_anim_flags |= ANIM_HAM6;
  377.                     }
  378.                     IFF_Setup_HMAP(act,iff_hmap,iff_cmap,iff_cmap_bits);
  379.                     iff_cur_hmap = (ColorReg *)act->data;
  380.  
  381.                     if (cmap_true_to_332 == TRUE)
  382.                     {
  383.                       iff_chdr = CMAP_Create_332(iff_cmap,&iff_imagec);
  384.               iff_or_mask = 0;
  385.                     }
  386.                     else /* if (cmap_true_to_gray == TRUE) */
  387.                     {
  388.                       iff_chdr = CMAP_Create_Gray(iff_cmap,&iff_imagec);
  389.               iff_or_mask = 0;
  390.                     }
  391.                     chdr_flag = TRUE;
  392.                   }
  393.                 }
  394.                 break;
  395.  
  396.         case CMAP:
  397.                 {
  398.           ULONG tmp;
  399.                   DEBUG_LEVEL2 fprintf(stderr,"IFF CMAP\n");
  400.  
  401.                   if (chunk.size == 0x40) 
  402.           {
  403.             iff_imagec = chunk.size / 2; /* xR+GB */
  404.             IFF_Read_CMAP_1(iff_cmap,iff_imagec,fin);
  405.           }
  406.                   else
  407.           {
  408.             iff_imagec = chunk.size / 3;  /* Rx+Gx+Bx 1 byte each */
  409.             IFF_Read_CMAP_0(iff_cmap,iff_imagec,fin);
  410.           }
  411.  
  412.                   /* Typically iff_imaged matches iff_imagec but not always 
  413.                    * HAM and EHB are frequent examples
  414.            */
  415.                   if (bmhd_flag)
  416.           {
  417.             tmp = 0x01 << iff_imaged;
  418.             if (tmp < iff_imagec) iff_imagec = tmp;
  419.           }
  420.  
  421.                   if (camg_flag & IFF_CAMG_HAM) 
  422.                   {
  423.                     XA_ACTION *act;
  424.                     if (iff_cmap_bits == 8)
  425.             {
  426.                       act = ACT_Get_Action(anim_hdr,ACT_IFF_HMAP8);
  427.               iff_anim_flags |= ANIM_HAM8;
  428.             }
  429.                     else
  430.             {
  431.                       act = ACT_Get_Action(anim_hdr,ACT_IFF_HMAP6);
  432.                       iff_anim_flags |= ANIM_HAM6;
  433.             }
  434.                     IFF_Setup_HMAP(act,iff_hmap,iff_cmap,iff_cmap_bits);
  435.                     iff_cur_hmap = (ColorReg *)act->data;
  436.  
  437.                     if (cmap_true_to_332 == TRUE)
  438.                     {
  439.                       iff_chdr = CMAP_Create_332(iff_cmap,&iff_imagec);
  440.                       iff_or_mask = 0;
  441.                     }
  442.                     else /* if (cmap_true_to_gray == TRUE) */
  443.                     {
  444.                       iff_chdr = CMAP_Create_Gray(iff_cmap,&iff_imagec);
  445.                       iff_or_mask = 0;
  446.                     }
  447.             chdr_flag = TRUE;
  448.                   }
  449.           else if (camg_flag & IFF_CAMG_EHB)
  450.           {
  451.                     IFF_Adjust_For_EHB(iff_cmap,iff_cmap_bits);
  452.                     iff_chdr =
  453.                       ACT_Get_CMAP(iff_cmap,iff_imagec,iff_or_mask,
  454.                 iff_imagec,iff_or_mask,
  455.                 iff_cmap_bits,iff_cmap_bits,iff_cmap_bits);
  456.             chdr_flag = TRUE;
  457.           }
  458.           else if (camg_flag) /* NOT HAM6,HAM8 or EHB */
  459.           {
  460.             if (iff_cmap_bits == 4) 
  461.             IFF_Shift_CMAP(iff_cmap,iff_imagec);
  462.                     iff_chdr = ACT_Get_CMAP(iff_cmap,iff_imagec,iff_or_mask,
  463.                 iff_imagec,iff_or_mask,
  464.                 iff_cmap_bits,iff_cmap_bits,iff_cmap_bits);
  465.             chdr_flag = TRUE;
  466.           }
  467.                   cmap_flag = TRUE;
  468.                 }
  469.                 break;
  470.  
  471.     case BODY:
  472.       {
  473.         XA_ACTION *act;
  474.         ACT_DLTA_HDR *dlta_hdr;
  475.  
  476.         DEBUG_LEVEL2 fprintf(stderr,"IFF BODY\n");
  477.         if (chdr_flag == FALSE)
  478.         {
  479.           if (cmap_flag==TRUE)
  480.           {   
  481.             if (iff_cmap_bits == 4) IFF_Shift_CMAP(iff_cmap,iff_imagec);
  482.             iff_chdr = ACT_Get_CMAP(iff_cmap,iff_imagec,iff_or_mask,
  483.                     iff_imagec,iff_or_mask,iff_cmap_bits,
  484.                     iff_cmap_bits,iff_cmap_bits);
  485.             chdr_flag = TRUE;
  486.             IFF_Register_CRNGs(anim_hdr,iff_chdr);
  487.             camg_flag = IFF_CAMG_NOP; /* so future CMAPs okay */
  488.           }   
  489.           else IFF_TheEnd1("IFF_Read_BODY: no cmap\n");
  490.         }
  491.  
  492.         act = ACT_Get_Action(anim_hdr,ACT_DELTA);
  493.         ACT_Add_CHDR_To_Action(act,iff_chdr);
  494.         act->h_cmap = iff_cur_hmap;
  495.         IFF_Add_Frame(1,act);
  496.  
  497. /* POD TEMP FINISH THIS eventually. For now body's are read in
  498.         if (xa_file_flag == TRUE)
  499.         {
  500.           dlta_hdr =(ACT_DLTA_HDR *)malloc(sizeof(ACT_DLTA_HDR));
  501.           if (dlta_hdr == 0) IFF_TheEnd1("IFF_Read_BODY: malloc err");
  502.           act->data = (UBYTE *)dlta_hdr;
  503.           dlta_hdr->flags = ACT_DBL_BUF;
  504.           dlta_hdr->fpos  = ftell(fin);
  505.           dlta_hdr->fsize = chunk.size;
  506.           fseek(fin,chunk.size,1);
  507.           if (chunk.size > iff_max_fsize) iff_max_fsize = chunk.size;
  508.         }
  509.         else
  510. */
  511.         {
  512.           dlta_hdr = (ACT_DLTA_HDR *) malloc( sizeof(ACT_DLTA_HDR)
  513.                         + (iff_imagex * iff_imagey) );
  514.           if (dlta_hdr == 0) IFF_TheEnd1("IFF_Read_BODY: malloc err");
  515.           act->data = (UBYTE *)dlta_hdr;
  516.           dlta_hdr->flags = ACT_DBL_BUF | DLTA_DATA;
  517.           dlta_hdr->fpos = 0; dlta_hdr->fsize = chunk.size;
  518.           IFF_Read_BODY(fin,dlta_hdr->data,chunk.size,
  519.                 iff_imagex, iff_imagey, iff_imaged,
  520.                 (int)(bmhd.compression),(int)(bmhd.masking),
  521.                 iff_or_mask);
  522.         }
  523.         dlta_hdr->delta = IFF_Delta_Body;
  524.         dlta_hdr->xsize = iff_imagex;    dlta_hdr->ysize = iff_imagey;
  525.         dlta_hdr->xpos = dlta_hdr->ypos = 0;
  526.         dlta_hdr->special = 0;
  527.         dlta_hdr->extra = 0;
  528.       }
  529.       break;
  530.  
  531.         case ANHD:
  532.         {
  533.           Anim_Header   anhd;
  534.           DEBUG_LEVEL2 fprintf(stderr,"IFF ANHD\n");
  535.           if (chunk.size >= Anim_Header_SIZE)
  536.           {
  537.             IFF_Read_ANHD(fin,&anhd,chunk.size);
  538.             iff_dlta_compression = anhd.op;
  539.             iff_dlta_bits = anhd.bits;
  540. /*
  541.             if (xa_verbose) 
  542.             fprintf(stderr,"ANHD time = %ld\n",anhd.reltime); 
  543. */
  544.           }
  545.           else 
  546.           {
  547.             IFF_Read_Garb(fin,chunk.size); 
  548.             iff_dlta_compression = 0xffffffff;
  549.             iff_dlta_bits = 0x0;
  550.             fprintf(stderr,"ANHD chunksize mismatch %ld\n",chunk.size);
  551.           }
  552.         }
  553.         break;
  554.  
  555.         case DLTA:
  556.       {
  557.         ACT_DLTA_HDR *dlta_hdr;
  558.         XA_ACTION *act;
  559.         DEBUG_LEVEL2 fprintf(stderr,"IFF DLTA: ");
  560.         act = ACT_Get_Action(anim_hdr,ACT_DELTA);
  561.         ACT_Add_CHDR_To_Action(act,iff_chdr);
  562.         act->h_cmap = iff_cur_hmap;
  563.           IFF_Add_Frame(1,act);
  564.  
  565.         if (xa_file_flag == TRUE)
  566.         {
  567.           dlta_hdr =(ACT_DLTA_HDR *)malloc(sizeof(ACT_DLTA_HDR));
  568.           if (dlta_hdr == 0) IFF_TheEnd1("IFF_Read_DLTA: malloc err");
  569.           act->data = (UBYTE *)dlta_hdr;
  570.           dlta_hdr->flags = ACT_DBL_BUF;
  571.           dlta_hdr->fpos  = ftell(fin);
  572.           dlta_hdr->fsize = chunk.size;
  573.           fseek(fin,chunk.size,1);
  574.           if (chunk.size > iff_max_fsize) iff_max_fsize = chunk.size;
  575.         }
  576.         else
  577.         {
  578.           dlta_hdr =(ACT_DLTA_HDR *)malloc(sizeof(ACT_DLTA_HDR)+chunk.size);
  579.           if (dlta_hdr == 0) IFF_TheEnd1("IFF_Read_DLTA: malloc err");
  580.           act->data = (UBYTE *)dlta_hdr;
  581.           dlta_hdr->flags = ACT_DBL_BUF | DLTA_DATA;
  582.           dlta_hdr->fpos = 0; dlta_hdr->fsize = chunk.size;
  583.           ret=fread(dlta_hdr->data,chunk.size,1,fin);
  584.         }
  585.  
  586.         dlta_hdr->xsize = iff_imagex;
  587.         dlta_hdr->ysize = iff_imagey;
  588.         dlta_hdr->xpos = dlta_hdr->ypos = 0;
  589.         dlta_hdr->special = 0;
  590.         dlta_hdr->extra = 0;
  591.         switch(iff_dlta_compression)
  592.         {
  593.           case  3:
  594.         DEBUG_LEVEL2 fprintf(stderr,"type 3\n");
  595.         dlta_hdr->delta = IFF_Delta_3;
  596.         break;
  597.           case 5:
  598.         DEBUG_LEVEL2 fprintf(stderr,"type 5\n");
  599.         dlta_hdr->delta = IFF_Delta_5;
  600.         break;
  601.           case 7:
  602.         dlta_hdr->delta = IFF_Delta_7;
  603.         if (iff_dlta_bits & IFF_ANHD_LDATA)
  604.         { 
  605.           DEBUG_LEVEL2 fprintf(stderr,"type 7L\n");
  606.           dlta_hdr->extra =  0;
  607.         } 
  608.         else 
  609.         { 
  610.           DEBUG_LEVEL2 fprintf(stderr,"type 7S\n");
  611.           dlta_hdr->extra =  1;
  612.         } 
  613.         break;
  614.           case 74:
  615.         DEBUG_LEVEL2 fprintf(stderr,"type J\n");
  616.         dlta_hdr->delta = IFF_Delta_J;
  617.         break;
  618.           case  108:
  619.         dlta_hdr->delta = IFF_Delta_l;
  620.         dlta_hdr->extra =  1;
  621.         DEBUG_LEVEL2 fprintf(stderr,"type l\n");
  622.         break;
  623.           default:  
  624.         act->type = ACT_NOP;
  625.         fprintf(stderr,"Unsupported Delta %ld\n",iff_dlta_compression);
  626.         break;
  627.         }
  628.       }
  629.     break;
  630.  
  631.     case ANSQ:
  632.       {
  633.         DEBUG_LEVEL2 fprintf(stderr,"IFF ANSQ\n");
  634.         ansq_flag = 1;  /* we found an ansq chunk */
  635.         IFF_Read_ANSQ(fin,chunk.size);
  636.       }
  637.       break;
  638.  
  639.         case CRNG: 
  640.       DEBUG_LEVEL2 fprintf(stderr,"IFF CRNG\n");
  641.       IFF_Read_CRNG(anim_hdr,fin,chunk.size,&crng_flag);
  642.       break;
  643.  
  644.     case TINY : /* ignore */
  645.     case DPI : /* ignore */
  646.     case IMRT: /* ignore */
  647.     case GRAB: /* ignore */
  648.     case DPPS: /* ignore */
  649.     case DPPV: /* ignore */
  650.     case DPAN: /* ignore */
  651.     case DRNG: /* ignore */
  652.     case VHDR: /* sound ignore should kill next body until bmhd*/
  653.     case ANNO: /* sound ignore */
  654.     case CHAN: /* sound ignore */
  655.     case ANFI: /* sound ignore */
  656.         if (chunk.size & 0x01) chunk.size++;
  657.                 ret = IFF_Read_Garb(fin,chunk.size);
  658.                 break;
  659.     default:
  660.     if ( feof(fin) ) exit_flag = 1;   /* end of file */
  661.     else
  662.     {
  663.       fprintf(stderr,"Unknown IFF type="); IFF_Print_ID(stderr,chunk.id);
  664.       if (   (file_read < file_size)    /* there should be more  */
  665.           && (chunk.size < (file_size - file_read) ) /*  size n 2 big */
  666.          )
  667.       {
  668.         fprintf(stderr,"  Will Continue Reading File.\n");
  669.         ret = IFF_Read_Garb(fin,chunk.size);
  670.       }
  671.       else
  672.       {
  673.         fprintf(stderr,"  Will Stop Reading File.\n");
  674.         exit_flag = 1;
  675.       }
  676.     }
  677.     break;
  678.    } /* end chunk switch */
  679.    /*
  680.     * keep track of number of bytes read. This allows us to distinguish
  681.     * valid unknown chunks from garbage tacked to the end of a file.
  682.     */
  683.    if (!exit_flag)
  684.    {
  685.      if (file_read == -1) file_read = 4; /* assuming FORM chunk or similar */
  686.      else file_read += chunk.size + 8; /* add ID and SIZE of other chunks */
  687.    }
  688.  
  689.   } /* end if ret==0 */
  690.  } /* end of while not eof or exit_flag */
  691.  DEBUG_LEVEL2 fprintf(stderr,"Bytes Read = %lx\n",file_read);
  692.  fclose(fin);
  693.  
  694.  /* 
  695.   * Set up a map of delta's to their action numbers.
  696.   */
  697.  {
  698.    ULONG i;
  699.    ULONG inter_dlta_i,dlta_i,act_i;
  700.  
  701.    iff_dlta_acts = 
  702.     (IFF_DLTA_TABLE *)malloc( (iff_dlta_cnt + 1) * sizeof(IFF_DLTA_TABLE));
  703.    if (iff_dlta_acts == 0) IFF_TheEnd1("IFF_Read_File: dlta_cnts malloc err");
  704.    for(i=0; i < iff_dlta_cnt; i++) 
  705.    {
  706.      iff_dlta_acts[i].cnt   = 0;
  707.      iff_dlta_acts[i].frame = 0;
  708.      iff_dlta_acts[i].start = 0;
  709.      iff_dlta_acts[i].end   = 0;
  710.    }
  711.    dlta_i = 0;
  712.    act_i = 0;
  713.    inter_dlta_i = 0;
  714.  
  715.    iff_act_cur = iff_act_start;
  716.    iff_dlta_acts[dlta_i].start = iff_act_cur;
  717.    iff_dlta_acts[dlta_i].frame = act_i;
  718.    while(iff_act_cur != 0)
  719.    {
  720.      inter_dlta_i++;
  721.      act_i++;
  722.      switch(iff_act_cur->act->type)
  723.      {
  724.        case ACT_DELTA:
  725.         iff_dlta_acts[dlta_i].cnt = inter_dlta_i;
  726.         iff_dlta_acts[dlta_i].end = iff_act_cur;
  727.         inter_dlta_i = 0;
  728.         iff_act_cur = iff_act_cur->next;
  729.         dlta_i++; 
  730.         if (dlta_i > iff_dlta_cnt)
  731.         {
  732.             fprintf(stderr,"IFF_Read: dlta setup err  <%ld > %ld> \n",
  733.                         dlta_i,iff_dlta_cnt);
  734.             IFF_TheEnd();
  735.         }
  736.         if (dlta_i < iff_dlta_cnt)
  737.         {
  738.           iff_dlta_acts[dlta_i].start = iff_act_cur;
  739.           iff_dlta_acts[dlta_i].frame = act_i;
  740.         }
  741.         break;
  742.        default:
  743.         iff_act_cur = iff_act_cur->next;
  744.         break;
  745.      }
  746.    } /* end of while */
  747.    DEBUG_LEVEL1 fprintf(stderr,"%ld dltas found\n",dlta_i);
  748.  
  749.    iff_time = XA_GET_TIME(IFF_SPEED_DEFAULT * MS_PER_60HZ);
  750.  
  751.    if (ansq_flag)
  752.    {
  753.      LONG i;
  754.      ULONG iff_frame_cnt,frame_i;
  755.  
  756.      iff_frame_cnt = iff_dlta_acts[0].cnt;  /* start with body cnt */
  757.      for(i=0; i < iff_ansq_cnt; i++) /* count frames */
  758.      {
  759.        if (iff_ansq[i].time != 0xffff) /* if not loop frame */
  760.       iff_frame_cnt += iff_dlta_acts[ iff_ansq[i].dnum + 1 ].cnt;
  761.      }
  762.      anim_hdr->frame_lst = 
  763.     (XA_FRAME *)malloc(sizeof(XA_FRAME) * (iff_frame_cnt + 1));
  764.      if (anim_hdr->frame_lst == NULL) 
  765.     IFF_TheEnd1("IFF ANSQ: frame_lst malloc err");
  766.   
  767.        /* For movies default loop frame is 0 */
  768.      anim_hdr->loop_frame = 0;
  769.  
  770.      /* take care of frame up to BODY */
  771.      frame_i = 0;
  772.      iff_act_cur = iff_dlta_acts[0].start;
  773.      while(iff_act_cur != 0)
  774.      {
  775.        anim_hdr->frame_lst[frame_i].act = iff_act_cur->act;
  776.        if (iff_act_cur == iff_dlta_acts[0].end)
  777.        {
  778.      anim_hdr->frame_lst[frame_i].time = iff_time;
  779.      frame_i++;
  780.      break;
  781.        }
  782.        else anim_hdr->frame_lst[frame_i].time = 1;
  783.        frame_i++;  
  784.        iff_act_cur = iff_act_cur->next;
  785.        if ( (frame_i > iff_frame_cnt) && (iff_act_cur != 0) )
  786.        {
  787.          fprintf(stderr,"IFF_ansq: frame err %ld %ld\n",frame_i,iff_frame_cnt);
  788.          IFF_TheEnd();
  789.        }
  790.      }
  791.      for(i=0; i < iff_ansq_cnt; i++)
  792.      {
  793.         if (iff_ansq[i].time == 0xffff) /* loop frame */
  794.         {
  795.           anim_hdr->loop_frame = iff_ansq[ iff_ansq[i].dnum ].frame;
  796.         }
  797.         else
  798.         {
  799.       ULONG dlta_j;
  800.       iff_ansq[i].frame = frame_i; /* for looping info */
  801.           dlta_j = iff_ansq[i].dnum + 1;
  802.           iff_time = XA_GET_TIME(iff_ansq[i].time * MS_PER_60HZ);
  803.       iff_act_cur = iff_dlta_acts[dlta_j].start;
  804.       while(iff_act_cur != 0)
  805.       {
  806.         anim_hdr->frame_lst[frame_i].act = iff_act_cur->act;
  807.             if (iff_act_cur == iff_dlta_acts[dlta_j].end) 
  808.         {
  809.           anim_hdr->frame_lst[frame_i].time = iff_time;
  810.           frame_i++;  
  811.           break;
  812.         }
  813.         else anim_hdr->frame_lst[frame_i].time = 1;
  814.         frame_i++;  
  815.             iff_act_cur = iff_act_cur->next;
  816.         if ( (frame_i > iff_frame_cnt) && (iff_act_cur != 0) )
  817.         {
  818.           fprintf(stderr,"IFF_ansq: frame err %ld %ld\n",
  819.                         frame_i,iff_frame_cnt);
  820.           IFF_TheEnd();
  821.         }
  822.       }
  823.         }
  824.       } /* end of for */
  825.       anim_hdr->frame_lst[frame_i].time = 0;
  826.       anim_hdr->frame_lst[frame_i].act  = 0;
  827.       anim_hdr->last_frame = frame_i - 1;
  828.     }
  829.     else   /* no ansq chunk */
  830.     {
  831.       LONG frame_i;
  832.  
  833.       /* extra for end and JMP2END */
  834.       anim_hdr->frame_lst = 
  835.       (XA_FRAME *)malloc(sizeof(XA_FRAME) * (iff_act_cnt + 2));
  836.       if (anim_hdr->frame_lst == NULL)
  837.         IFF_TheEnd1("IFF_Read: frame malloc err");
  838.       iff_act_cur = iff_act_start;
  839.       frame_i = 0;
  840.       while(iff_act_cur != 0)
  841.       {
  842.         anim_hdr->frame_lst[frame_i].act  = iff_act_cur->act;
  843.     if (iff_act_cur->type == 1)
  844.     {
  845.       if ( (iff_dlta_cnt == 1) && (crng_flag) && (xa_jiffy_flag == 0) )
  846. /* && (iff_act_cur->act->type == ACT_IFF_BODY) ) */
  847.       {
  848.             anim_hdr->frame_lst[frame_i].time = DEFAULT_CYCLING_TIME;
  849.       }
  850.           else  anim_hdr->frame_lst[frame_i].time = iff_time;
  851.     }
  852.     else  anim_hdr->frame_lst[frame_i].time = 1;
  853.         iff_act_cur = iff_act_cur->next;
  854.         frame_i++;
  855.         if (frame_i > iff_act_cnt)
  856.         {
  857.           fprintf(stderr,"IFF_Read: frame inconsistency %ld %ld\n",
  858.                 frame_i,iff_act_cnt);
  859.           IFF_TheEnd();
  860.         }
  861.       }
  862.       /* Add JMP2END so deltas to beginning aren't displayed unless looping */
  863.       if ( !(iff_anim_flags & ANIM_NOLOOP) && (iff_dlta_cnt > 3) && !face_flag)
  864.       { ULONG kk = frame_i;
  865.     anim_hdr->frame_lst[kk].time = anim_hdr->frame_lst[kk-1].time;
  866.     anim_hdr->frame_lst[kk].act  = anim_hdr->frame_lst[kk-1].act;
  867.     anim_hdr->frame_lst[kk-1].time = anim_hdr->frame_lst[kk-2].time;
  868.     anim_hdr->frame_lst[kk-1].act  = anim_hdr->frame_lst[kk-2].act;
  869.         anim_hdr->frame_lst[kk-2].time = 0;
  870.     anim_hdr->frame_lst[kk-2].act = ACT_Get_Action(anim_hdr,ACT_JMP2END);
  871.         frame_i++;
  872.         anim_hdr->loop_frame = iff_dlta_acts[2].frame;
  873.       }
  874.       else
  875.       {
  876.     anim_hdr->loop_frame = 0; 
  877.       }
  878.       if (frame_i > 0 ) anim_hdr->last_frame = frame_i - 1;
  879.       else anim_hdr->last_frame = 0;
  880.       anim_hdr->frame_lst[frame_i].time = 0;
  881.       anim_hdr->frame_lst[frame_i].act  = 0;
  882.       frame_i++;
  883.       if (xa_verbose) 
  884.       {
  885.     fprintf(stderr,"     dlta_cnt=%ld comp=%ld ",
  886.                 iff_dlta_cnt,iff_dlta_compression);
  887.     if (camg_flag & IFF_CAMG_EHB) fprintf(stderr," EHB\n");
  888.     else if (iff_anim_flags & ANIM_HAM8) fprintf(stderr," HAM8\n");
  889.     else if (iff_anim_flags & ANIM_HAM6) fprintf(stderr," HAM6\n");
  890.     else fprintf(stderr,"\n");
  891.       }
  892.     }
  893.   }
  894.   anim_hdr->imagex = iff_max_imagex;
  895.   anim_hdr->imagey = iff_max_imagey;
  896.   anim_hdr->imagec = iff_imagec;
  897.   anim_hdr->imaged = iff_max_imaged;
  898.  
  899.   /* Some older IFF files don't include a CAMG chunk to indicate they
  900.    * are interlaced. They just assume the viewer will figure it out.
  901.    * Below is an arbitrary ruleset that'll hopefully work for most cases.
  902.    */
  903.    if ((iff_max_imagex >= 400) && (iff_max_imagey > iff_max_imagex))
  904.     iff_anim_flags |= ANIM_LACE;
  905.  
  906.   /* NOTE: A lot of IFF animations have active color cycle chunks, yet
  907.    *       they were never intended to cycle. AAARRRRGH!!!
  908.    */
  909.   if (iff_dlta_cnt == 1)  /* single image IFF files */
  910.   {
  911.     if ( (crng_flag) && (iff_allow_cycling == TRUE) )
  912.                     iff_anim_flags |= ANIM_CYCLE;
  913.     else iff_anim_flags &= ~ANIM_CYCLE;
  914.   }
  915.   else /* animation IFF files */
  916.   {
  917.     if ( (crng_flag) && (iff_allow_cycling == TRUE) 
  918.         && (xa_anim_cycling == TRUE) )   iff_anim_flags |= ANIM_CYCLE;
  919.     else iff_anim_flags &= ~ANIM_CYCLE;
  920.   }
  921.   anim_hdr->anim_flags = iff_anim_flags;
  922.   IFF_Free_Stuff();
  923.   iff_chdr = 0;
  924.   if (xa_buffer_flag) IFF_Buffer_Action(anim_hdr);
  925.   else
  926.   {
  927.     anim_hdr->anim_flags |= ANIM_SNG_BUF;
  928.     if (iff_dlta_cnt > 1) anim_hdr->anim_flags |= ANIM_DBL_BUF;
  929.     if (iff_anim_flags | ANIM_HAM) anim_hdr->anim_flags |= ANIM_3RD_BUF;
  930.   }
  931.   if (xa_file_flag==TRUE) anim_hdr->anim_flags |= ANIM_USE_FILE;
  932.   anim_hdr->fname = anim_hdr->name;
  933.   anim_hdr->max_fsize = iff_max_fsize;
  934.   return(TRUE);
  935. }
  936.  
  937. /*
  938.  *
  939.  */
  940. void IFF_Adjust_For_EHB(colormap,cmap_bits)
  941. ColorReg colormap[];
  942. ULONG cmap_bits;
  943. {
  944.   LONG i,cmap_num;
  945.  
  946.   DEBUG_LEVEL1 
  947.     fprintf(stderr,"Adjusting CMAP for Amiga Extra Half-Brite Mode\n");
  948.   if (cmap_bits == 8) cmap_num = 128;
  949.   else 
  950.   { /* 4 bits per rgb, shift down from 8 bits to 4 bits */
  951.     cmap_num = 32;
  952.     IFF_Shift_CMAP(colormap,cmap_num);
  953.   }
  954.  
  955.    /* make upper half a darkened version of the lower half */
  956.   for(i=0;i<cmap_num;i++)
  957.   {
  958.     colormap[i + cmap_num].red   = colormap[i].red   >> 2;
  959.     colormap[i + cmap_num].green = colormap[i].green >> 2;
  960.     colormap[i + cmap_num].blue  = colormap[i].blue  >> 2;
  961.   }
  962.   iff_imagec = 2 * cmap_num;
  963.   iff_or_mask = CMAP_Get_Or_Mask(iff_imagec);
  964. }
  965.  
  966.  
  967. /*
  968.  *
  969.  */
  970. void IFF_Read_BODY(fin,image_out,bodysize,xsize,ysize,depth,
  971.             compression,masking,or_mask)
  972. FILE *fin;
  973. UBYTE *image_out;
  974. ULONG xsize,ysize,depth;
  975. LONG bodysize,compression,masking;
  976. ULONG or_mask;
  977. {
  978.  LONG i,ret,x,y,d,dmask,tmp,rowsize;
  979.  LONG imagex_pad;
  980.  BYTE *inbuff,*rowbuff,*sptr;
  981.  BYTE *sbuff,*dbuff;
  982.  
  983.  if (   (compression != BMHD_COMP_NONE) 
  984.      && (compression != BMHD_COMP_BYTERUN) 
  985.     ) IFF_TheEnd1("IFF_Read_Body: unsupported compression");
  986.  
  987.  if (   (masking != BMHD_MSK_NONE)
  988.      && (masking != BMHD_MSK_HAS)
  989.      && (masking != BMHD_MSK_TRANS)
  990.     ) IFF_TheEnd1("IFF_Read_Body: unsupported masking");
  991.  
  992.  inbuff = (BYTE *)malloc(bodysize);
  993.  if (inbuff == 0) IFF_TheEnd1("IFF_Read_Body: malloc failed");
  994.  ret=fread(inbuff,bodysize,1,fin);
  995.  if (ret!=1) IFF_TheEnd1("IFF_Read_Body: read of BODY chunk failed");
  996.  sbuff = inbuff;
  997.  
  998.  
  999.  /* width is rounded to multiples of 16 in the BODY form */
  1000.  /* extra bits are ignored upon reading */
  1001.  imagex_pad = xsize / 16;
  1002.  if (xsize % 16) imagex_pad++;
  1003.  imagex_pad *= 16;
  1004.  
  1005.  rowbuff = (BYTE *)malloc( imagex_pad );
  1006.  if (rowbuff == 0) IFF_TheEnd1("IFF_Read_Body: malloc failed");
  1007.  
  1008.  memset(image_out,or_mask,(xsize * ysize) );
  1009.  
  1010.  if (compression==BMHD_COMP_NONE) sptr = inbuff;
  1011.  
  1012.  for(y=0; y<ysize; y++)
  1013.  {
  1014.    tmp = y * xsize;
  1015.    dmask=1;
  1016.    for(d=0; d<depth; d++)
  1017.    {
  1018.  
  1019.      if (compression == BMHD_COMP_BYTERUN)
  1020.      {
  1021.        rowsize = imagex_pad / 8; 
  1022.        dbuff = rowbuff;
  1023.        ret=UnPackRow(&sbuff,&dbuff,&bodysize,&rowsize);
  1024.        if (ret) { fprintf(stderr,"error %ld in unpack\n",ret); IFF_TheEnd();}
  1025.        sptr = rowbuff;
  1026.      }
  1027.  
  1028.      i = 0;
  1029.      for(x=0; x<xsize; x++)
  1030.      {
  1031.        if (mask[i] & (*sptr)) image_out[tmp+x] |= dmask;
  1032.        i++;
  1033.        if (i >= 8)
  1034.        {
  1035.      i = 0;
  1036.      sptr++;
  1037.        }
  1038.      }
  1039.      if (imagex_pad >= (xsize+8)) sptr++;
  1040.  
  1041.      dmask <<= 1;
  1042.    } /* end of depth loop */
  1043.  
  1044.    if (masking == BMHD_MSK_HAS)
  1045.    {
  1046.      /* read the mask row and then throw out for now */
  1047.      if (compression == BMHD_COMP_BYTERUN)
  1048.      {
  1049.        rowsize = imagex_pad / 8;
  1050.        dbuff = rowbuff;
  1051.        ret=UnPackRow(&sbuff,&dbuff,&bodysize,&rowsize);
  1052.        if (ret) { fprintf(stderr,"error %ld in unpack\n",ret); IFF_TheEnd();}
  1053.      }
  1054.      else sptr += xsize/8;
  1055.    }
  1056.  } /* end of y loop */
  1057.  FREE(inbuff,0x1004);  inbuff=0;
  1058.  FREE(rowbuff,0x1005); rowbuff=0;
  1059. }
  1060.  
  1061.  
  1062. /*
  1063.  *
  1064.  */
  1065. LONG IFF_Read_Garb(fp,size)
  1066. FILE *fp;
  1067. LONG size;
  1068. {
  1069.  BYTE *garb;
  1070.  
  1071.  garb = (BYTE *)malloc(size);
  1072.  if (garb==0)
  1073.  { fprintf(stderr,"readgarb malloc err size=%ld",size); return(-1);}
  1074.  fread(garb,size,1,fp);
  1075.  FREE(garb,0x1006); garb=0;
  1076.  return(0);
  1077. }
  1078.  
  1079. void IFF_Print_ID(fout,id)
  1080. FILE *fout;
  1081. LONG id;
  1082. {
  1083.  fprintf(fout,"%c",     ((id >> 24) & 0xff)   );
  1084.  fprintf(fout,"%c",     ((id >> 16) & 0xff)   );
  1085.  fprintf(fout,"%c",     ((id >>  8) & 0xff)   );
  1086.  fprintf(fout,"%c(%lx)", (id        & 0xff),id);
  1087. }
  1088.  
  1089.  
  1090. /* 
  1091.  *
  1092.  */
  1093. ULONG
  1094. IFF_Delta_5(image,delta,dsize,chdr,map,map_flag,imagex,imagey,imaged,
  1095.                         xs,ys,xe,ye,special,extra)
  1096. UBYTE *image;        /* Image Buffer. */
  1097. UBYTE *delta;        /* delta data. */
  1098. ULONG dsize;        /* delta size */
  1099. XA_CHDR *chdr;        /* color map info */
  1100. ULONG *map;        /* used if it's going to be remapped. */
  1101. ULONG map_flag;        /* whether or not to use remap_map info. */
  1102. ULONG imagex,imagey;    /* Size of image buffer. */
  1103. ULONG imaged;        /* Depth of Image. (IFF specific) */
  1104. ULONG *xs,*ys;        /* pos of changed area. */
  1105. ULONG *xe,*ye;        /* size of changed area. */
  1106. ULONG special;        /* Special Info. */
  1107. ULONG extra;        /* Extra Info. */
  1108. {
  1109.  register LONG col,depth,dmask;
  1110.  register LONG rowsize,width;
  1111.  ULONG poff;
  1112.  register UBYTE *i_ptr;
  1113.  register UBYTE *dptr,opcnt,op,cnt;
  1114.  LONG miny,minx,maxy,maxx;
  1115.  
  1116.  /* set to opposites for min/max testing */
  1117.  *xe = *ye = 0; *ys = imagey; *xs = imagex;
  1118.  
  1119.  width = imagex;
  1120.  rowsize = width >> 3;
  1121.  dmask = 1;
  1122.  for(depth=0; depth<imaged; depth++)
  1123.  {
  1124.   minx = -1;
  1125.   maxx = -1;
  1126.   
  1127.   i_ptr = image;
  1128.   /* offset into delt chunk */
  1129.   { register USHORT ddepth = depth << 2;
  1130.     poff  = (ULONG)(delta[ ddepth++ ]) << 24;
  1131.     poff |= (ULONG)(delta[ ddepth++ ]) << 16;
  1132.     poff |= (ULONG)(delta[ ddepth++ ]) <<  8;
  1133.     poff |= (ULONG)(delta[ ddepth   ]);
  1134.   }
  1135.  
  1136.   if (poff)
  1137.   {
  1138.    dptr = (UBYTE *)(delta + poff);
  1139.    for(col=0;col<rowsize;col++)
  1140.    {
  1141.     /* start at top of column */
  1142.     i_ptr = (UBYTE *)(image + (col << 3));
  1143.     opcnt = *dptr++;  /* get number of ops for this column */
  1144.     
  1145.     miny = -1;
  1146.     maxy = -1;
  1147.  
  1148.     while(opcnt)    /* execute ops */
  1149.     {
  1150.        /* keep track of min and max columns */
  1151.        if (minx == -1) minx = col << 3;
  1152.        maxx = (col << 3) + 7;  
  1153.  
  1154.        op = *dptr++;   /* get op */
  1155.      
  1156.        if (op & 0x80)    /* if type uniqe */
  1157.        {
  1158.           if (miny == -1) miny=(ULONG)( i_ptr - image ) / width;
  1159.           cnt = op & 0x7f;         /* get cnt */
  1160.       
  1161.           while(cnt--) /* loop through data */
  1162.           {
  1163.              register UBYTE data = *dptr++;
  1164.              IFF_Byte_Mod(i_ptr,data,dmask,0);
  1165.              i_ptr += width;
  1166.           }
  1167.         } /* end unique */
  1168.         else
  1169.         {
  1170.            if (op == 0)   /* type same */
  1171.            {
  1172.               register UBYTE data;
  1173.               if (miny == -1) miny=(ULONG)( i_ptr - image ) / width;
  1174.               cnt = *dptr++;
  1175.               data = *dptr++;
  1176.  
  1177.               while(cnt--) /* loop through data */
  1178.               { 
  1179.                  IFF_Byte_Mod(i_ptr,data,dmask,0);
  1180.                  i_ptr += width;
  1181.               }
  1182.             } /* end same */
  1183.             else
  1184.             {
  1185.                i_ptr += (width * op);  /* type skip */
  1186.             }
  1187.          } /* end of hi bit clear */
  1188.        opcnt--;
  1189.      } /* end of while opcnt */
  1190.      maxy = (ULONG)( i_ptr - image ) / width;
  1191.      if ( (miny>=0) && (miny < *ys)) *ys = miny;
  1192.      if ( (maxy>=0) && (maxy > *ye)) *ye = maxy;
  1193.     } /* end of column loop */
  1194.    } /* end of valid pointer for this plane */
  1195.    dmask <<= 1;
  1196.    if ( (minx>=0) && (minx < *xs)) *xs = minx;
  1197.    if ( (maxx>=0) && (maxx > *xe)) *xe = maxx;
  1198.   } /* end of for depth */
  1199.  
  1200.   if (xa_optimize_flag == TRUE)
  1201.   {
  1202.     if (*xs >= imagex) *xs = 0;
  1203.     if (*ys >= imagey) *ys = 0;
  1204.     if (*xe <= 0)      *xe = imagex;
  1205.     if (*ye <= 0)      *ye = imagey;
  1206.   }
  1207.   else
  1208.   {
  1209.     *xs = 0;      *ys = 0;
  1210.     *xe = imagex; *ye = imagey;
  1211.   }
  1212.   return(ACT_DLTA_NORM); 
  1213. } /* end of routine */
  1214.  
  1215. /*
  1216.  * 
  1217.  */
  1218. ULONG
  1219. IFF_Delta_3(image,delta,dsize,chdr,map,map_flag,imagex,imagey,imaged,
  1220.                         xs,ys,xe,ye,special,extra)
  1221. UBYTE *image;        /* Image Buffer. */
  1222. UBYTE *delta;        /* delta data. */
  1223. ULONG dsize;        /* delta size */
  1224. XA_CHDR *chdr;        /* color map info */
  1225. ULONG *map;        /* used if it's going to be remapped. */
  1226. ULONG map_flag;        /* whether or not to use remap_map info. */
  1227. ULONG imagex,imagey;    /* Size of image buffer. */
  1228. ULONG imaged;        /* Depth of Image. (IFF specific) */
  1229. ULONG *xs,*ys;        /* pos of changed area. */
  1230. ULONG *xe,*ye;        /* size of changed area. */
  1231. ULONG special;        /* Special Info. */
  1232. ULONG extra;        /* Extra Info. */
  1233. {
  1234.  register LONG i,depth,dmask;
  1235.  ULONG poff;
  1236.  register SHORT  offset;
  1237.  register USHORT s,data;
  1238.  register UBYTE  *i_ptr,*dptr;
  1239.  
  1240.  *xs = *ys = 0; *xe = imagex; *ye = imagey;
  1241.  dmask = 1;
  1242.  for(depth=0;depth<imaged;depth++)
  1243.  {
  1244.   i_ptr = image;
  1245.  
  1246.   /*poff = planeoff[depth];*/ /* offset into delt chunk */
  1247.  
  1248.   poff  = (ULONG)(delta[ 4 * depth    ]) << 24;
  1249.   poff |= (ULONG)(delta[ 4 * depth + 1]) << 16;
  1250.   poff |= (ULONG)(delta[ 4 * depth + 2]) <<  8;
  1251.   poff |= (ULONG)(delta[ 4 * depth + 3]);
  1252.  
  1253.   if (poff)
  1254.   {
  1255.    dptr = (UBYTE *)(delta + poff);
  1256.    while( (dptr[0] != 0xff) || (dptr[1] != 0xff) )
  1257.    {
  1258.      offset = (*dptr++)<<8; offset |= (*dptr++);
  1259.      if (offset >= 0)
  1260.      {
  1261.       data = (*dptr++)<<8; data |= (*dptr++);
  1262.       i_ptr += 16 * (ULONG)(offset);
  1263.       IFF_Short_Mod(i_ptr,data,dmask,0);
  1264.      } /* end of pos */
  1265.      else
  1266.      {
  1267.       i_ptr += 16 * (ULONG)(-(offset+2));
  1268.       s = (*dptr++)<<8; s |= (*dptr++); /* size of next */
  1269.       for(i=0; i < (ULONG)s; i++)
  1270.       {
  1271.        data = (*dptr++)<<8; data |= (*dptr++);
  1272.        i_ptr += 16;
  1273.        IFF_Short_Mod(i_ptr,data,dmask,0);
  1274.       }
  1275.     }  /* end of neg */
  1276.    } /* end of delta for this plane */
  1277.   } /* plane has changed data */
  1278.   dmask <<= 1;
  1279.  } /* end of d */
  1280.  return(ACT_DLTA_NORM); 
  1281. }
  1282.  
  1283. /* 
  1284.  *
  1285.  */
  1286. LONG Is_IFF_File(filename)
  1287. BYTE *filename;
  1288. {
  1289.  FILE *fp;
  1290.  ULONG firstword;
  1291.  
  1292.  if ( (fp=fopen(filename,XA_OPEN_MODE)) == 0) return(XA_NOFILE);
  1293.   /* by reading bytes we can ignore big/little endian problems */
  1294.  firstword  = (fgetc(fp) & 0xff) << 24;
  1295.  firstword |= (fgetc(fp) & 0xff) << 16;
  1296.  firstword |= (fgetc(fp) & 0xff) <<  8;
  1297.  firstword |= (fgetc(fp) & 0xff);
  1298.  
  1299.  fclose(fp);
  1300.  
  1301.  if (firstword == FORM) return(TRUE);
  1302.  if (firstword == LIST) return(TRUE);
  1303.  if (firstword == PROP) return(TRUE);
  1304.  return(FALSE);
  1305. }
  1306.  
  1307. void IFF_Hash_Init(num)
  1308. ULONG num;
  1309. { register ULONG i;
  1310.   iff_hash_cur=0;
  1311.   iff_hash_tbl = (IFF_HASH *)malloc(num * sizeof(IFF_HASH));
  1312.   if (iff_hash_tbl == 0) TheEnd1("IFF_Hash_Init: malloc err");
  1313.   for(i=0;i<num;i++) iff_hash_tbl[i].flag = ACT_DLTA_BAD;
  1314. }
  1315.  
  1316. void IFF_Hash_CleanUp()
  1317. {
  1318.   if (iff_hash_tbl)
  1319.   { register ULONG i=0;
  1320.     while(i<iff_hash_cur)
  1321.     {
  1322.       register XA_ACTION *tact = iff_hash_tbl[i].dlta;
  1323.       if (tact)
  1324.       {
  1325.     if (tact->type == ACT_DELTA) ACT_Free_Act(tact);
  1326.       }
  1327.       i++;
  1328.     }
  1329.     FREE(iff_hash_tbl,0x100E); iff_hash_tbl=0;
  1330.   }
  1331. }
  1332.  
  1333. void IFF_Hash_Add(dlta,nxtdlta,src,dst,flag)
  1334. XA_ACTION *dlta,*nxtdlta,*src,**dst;
  1335. ULONG flag;
  1336.   register IFF_HASH *hptr = &iff_hash_tbl[iff_hash_cur];
  1337.   hptr->flag = flag;    
  1338.   hptr->dlta = dlta;    hptr->nxtdlta = nxtdlta;
  1339.   hptr->src = src;    hptr->dst = *dst;
  1340.   iff_hash_cur++;
  1341. }
  1342.  
  1343. ULONG pod_temp_i;
  1344. XA_ACTION *IFF_Hash_Get(dlta,src,nxtdlta)
  1345. XA_ACTION *dlta,*src,*nxtdlta;
  1346. { register ULONG i = 0;
  1347.   while(1)
  1348.   { IFF_HASH *hptr = &iff_hash_tbl[i];
  1349. pod_temp_i = i;
  1350.     if (hptr->flag & ACT_DLTA_BAD) return(0); /* end and nothing found */
  1351.     else if (hptr->dlta == dlta)
  1352.     {
  1353.       if (hptr->flag & ACT_DLTA_NOP)            return(src);
  1354.       else if (    (src == hptr->src)
  1355.         || (hptr->flag & ACT_DLTA_BODY) )    return(hptr->dst);
  1356.       else if (    (src == hptr->dst)
  1357.         && (hptr->flag & ACT_DLTA_XOR) )    return(hptr->src);
  1358.       else if (hptr->nxtdlta == nxtdlta)        return(hptr->dst);
  1359.     }
  1360.     i++;
  1361.   }
  1362. }
  1363.  
  1364.  
  1365. /* 
  1366.  *
  1367.  */
  1368. void IFF_Buffer_Action(anim_hdr)
  1369. XA_ANIM_HDR *anim_hdr;
  1370. {
  1371.   LONG image_size;
  1372.   UBYTE *buff0,*buff1,*tmp,*dbl_buff;
  1373.   XA_ACTION *act,*old_act0,*old_act1;
  1374.   XA_FRAME *frame_lst;
  1375.   ULONG frame_i,frame_num;
  1376.   ULONG scale_x,scale_y,need_to_scale;
  1377.  
  1378.   iff_chdr = 0;
  1379.   image_size = iff_imagex * iff_imagey;
  1380.   dbl_buff = buff1 = buff0 = (UBYTE *) malloc( 2 * image_size );
  1381.   if (buff0 == 0) TheEnd1("IFF Buffer Action: malloc failed 0");
  1382.   buff1 += image_size;
  1383.   frame_num = anim_hdr->last_frame + 1;
  1384.  
  1385.   IFF_Hash_Init(frame_num);
  1386.   need_to_scale = 
  1387.     UTIL_Get_Buffer_Scale(iff_imagex,iff_imagey,&scale_x,&scale_y);
  1388.  
  1389.   frame_i = 0;  old_act0 = old_act1 = 0;
  1390.   frame_lst = anim_hdr->frame_lst; 
  1391.   while(frame_lst[frame_i].act != 0)
  1392.   {
  1393.     XA_ACTION *dst_act,*new_act,*nxt_act;
  1394.  
  1395.  
  1396.     act = frame_lst[frame_i].act;
  1397.     nxt_act = frame_lst[frame_i + 1].act;
  1398.  
  1399.       switch(act->type)
  1400.       {
  1401.     case ACT_DELTA:
  1402.         {
  1403.       ACT_DLTA_HDR *dlta_hdr = (ACT_DLTA_HDR *)act->data;
  1404.           LONG minx,miny,maxx,maxy; 
  1405.           LONG pic_x,pic_y;
  1406.           UBYTE *t_pic;
  1407.       ULONG dlta_flag = 1;
  1408.  
  1409.       dlta_flag = dlta_hdr->delta(buff0, dlta_hdr->data, 
  1410.         dlta_hdr->fsize, 0, 0, FALSE,
  1411.         iff_imagex,iff_imagey,iff_imaged,
  1412.         &minx, &miny, &maxx, &maxy, dlta_hdr->special,dlta_hdr->extra);
  1413.  
  1414.           if (dlta_flag & ACT_DLTA_BODY)
  1415.       {
  1416.         memcpy((char *)buff1, (char *)buff0, image_size);
  1417.         maxx = dlta_hdr->xsize; maxy = dlta_hdr->ysize;
  1418.             IFF_Init_DLTA_HDR(maxx,maxy);
  1419.       }
  1420.  
  1421.  
  1422.           IFF_Update_DLTA_HDR(&minx,&miny,&maxx,&maxy);
  1423.       dst_act = IFF_Hash_Get(act,old_act0,nxt_act); 
  1424.     /* IF unbuffered action has been previously setup and IF it's
  1425.      * smaller than old one, use the old one. IF it's larger than
  1426.      * the old one, then free up the old one and replace with this one.
  1427.      * Same goes for deltas that don't change an images(the NOPs).
  1428.      */
  1429.       if ( (dst_act) || (dlta_flag & ACT_DLTA_NOP) )
  1430.       {
  1431.         XA_ACTION *tst_act;
  1432.         if (!dst_act) /* if here because no change */
  1433.         {
  1434.           if (old_act0 == 0) TheEnd1("IFF Buff: No Body err");
  1435.           IFF_Hash_Add(act,nxt_act,old_act0,&old_act0,dlta_flag);
  1436.           tst_act = old_act0;
  1437.         } else tst_act = dst_act;
  1438.  
  1439.             if ( (tst_act->type==ACT_MAPPED) || (tst_act->type==ACT_DISP) )
  1440.         { 
  1441.           ACT_MAPPED_HDR *maphdr = (ACT_MAPPED_HDR *)tst_act->data;
  1442.           ULONG px,py,sx,sy;
  1443.           ULONG opx,opy,osx,osy;
  1444.           px = minx;  sx = maxx - minx; py = miny;  sy = maxy - miny;
  1445.           if (need_to_scale) UTIL_Scale_Pos_Size(&px,&py,&sx,&sy,
  1446.                     iff_imagex,iff_imagey,scale_x,scale_y);
  1447.           sx += px;    opx = maphdr->xpos;    osx = maphdr->xsize + opx;
  1448.           sy += py;    opy = maphdr->ypos;    osy = maphdr->ysize + opy;
  1449.           if (   ((px >= opx) && (px <= osx))  /* new is <= old */
  1450.               && ((sx >= opx) && (sx <= osx))
  1451.               && ((py >= opy) && (py <= osy))
  1452.               && ((sy >= opy) && (sy <= osy)) )
  1453.           {
  1454.         frame_lst[frame_i].act = tst_act;
  1455.         old_act0 = old_act1; old_act1 = tst_act;
  1456.         tmp = buff0; buff0 = buff1; buff1 = tmp;
  1457.         break;
  1458.           }
  1459.         } /* NOTE: this might should be an error */
  1460.         ACT_Free_Act(tst_act);
  1461.         new_act = tst_act;   /* free_act should wipe chdr info */ 
  1462.       }
  1463.       else 
  1464.       {
  1465.           /* get new action for unbuffered frame */
  1466.         new_act = ACT_Get_Action(anim_hdr,0);
  1467.         ACT_Add_CHDR_To_Action(new_act,act->chdr);
  1468.       }
  1469.  
  1470.           pic_x = maxx - minx; pic_y = maxy - miny;
  1471.       /* now get into shape */
  1472.           if (iff_anim_flags & ANIM_HAM)
  1473.       { 
  1474.         ULONG disp_flag;
  1475.  
  1476.         if (x11_display_type == XA_MONOCHROME)
  1477.         {minx=miny=0; pic_x=iff_imagex; pic_y=iff_imagey; }
  1478.  
  1479.             t_pic = (UBYTE *) malloc( XA_PIC_SIZE(pic_x * pic_y) );
  1480.         if (x11_display_type & XA_X11_TRUE) disp_flag = TRUE;
  1481.         else disp_flag = FALSE;
  1482.         if (iff_anim_flags & ANIM_HAM6)
  1483.         {
  1484.           if (cmap_true_map_flag == TRUE)
  1485.           {
  1486.             XA_CHDR *tmp_chdr = 0;
  1487.         ACT_Del_CHDR_From_Action(new_act,new_act->chdr);
  1488.         IFF_HAM6_As_True (t_pic,buff0,&tmp_chdr,act->h_cmap,
  1489.             pic_x,pic_y,minx,miny,iff_imagex);
  1490.         ACT_Add_CHDR_To_Action(new_act,tmp_chdr);
  1491.            }
  1492.           else
  1493.          IFF_Buffer_HAM6(t_pic,buff0,new_act->chdr,act->h_cmap,
  1494.             pic_x,pic_y,minx,miny,iff_imagex,FALSE);
  1495.         }
  1496.         else
  1497.         {
  1498.           if (cmap_true_map_flag == TRUE)
  1499.           {
  1500.             XA_CHDR *tmp_chdr = 0;
  1501.         ACT_Del_CHDR_From_Action(new_act,new_act->chdr);
  1502.         IFF_HAM8_As_True (t_pic,buff0,&tmp_chdr,act->h_cmap,
  1503.             pic_x,pic_y,minx,miny,iff_imagex);
  1504.         ACT_Add_CHDR_To_Action(new_act,tmp_chdr);
  1505.            }
  1506.           else
  1507.         IFF_Buffer_HAM8(t_pic,buff0,new_act->chdr,act->h_cmap,
  1508.             pic_x,pic_y,minx,miny,iff_imagex,FALSE);
  1509.         }
  1510.         ACT_Setup_Mapped(new_act, t_pic, new_act->chdr, 
  1511.         minx, miny, pic_x, pic_y, iff_imagex, iff_imagey,
  1512.         FALSE, 0, TRUE, FALSE, disp_flag);
  1513.       }
  1514.       else ACT_Setup_Mapped(new_act, buff0, new_act->chdr, 
  1515.         minx, miny, pic_x, pic_y, iff_imagex, iff_imagey,
  1516.         FALSE,0, FALSE, TRUE, FALSE);
  1517.           if (dlta_flag & ACT_DLTA_BODY) old_act0 = old_act1 = new_act;
  1518.       IFF_Hash_Add(act,nxt_act,old_act0,&new_act,dlta_flag);
  1519.       old_act0 = old_act1; old_act1 = new_act; 
  1520.       frame_lst[frame_i].act = new_act;
  1521.           tmp = buff0; buff0 = buff1; buff1 = tmp;
  1522.         } /* end of delta7,5,j */
  1523.         break;
  1524.       } /* end of switch */
  1525.     frame_i++; /* move to next action in list */
  1526.   } /* end of while */
  1527.   if (dbl_buff) { FREE(dbl_buff,0x100A); dbl_buff = buff0 = buff1 = 0;}
  1528.   IFF_Hash_CleanUp();
  1529.   iff_chdr = 0;
  1530. }
  1531.  
  1532. ULONG
  1533. IFF_Delta_J(image,delta,dsize,chdr,map,map_flag,imagex,imagey,imaged,
  1534.                         xs,ys,xe,ye,special,extra)
  1535. UBYTE *image;        /* Image Buffer. */
  1536. UBYTE *delta;        /* delta data. */
  1537. ULONG dsize;        /* delta size */
  1538. XA_CHDR *chdr;        /* color map info */
  1539. ULONG *map;        /* used if it's going to be remapped. */
  1540. ULONG map_flag;        /* whether or not to use remap_map info. */
  1541. ULONG imagex,imagey;    /* Size of image buffer. */
  1542. ULONG imaged;        /* Depth of Image. (IFF specific) */
  1543. ULONG *xs,*ys;        /* pos of changed area. */
  1544. ULONG *xe,*ye;        /* size of changed area. */
  1545. ULONG special;        /* Special Info. */
  1546. ULONG extra;        /* Extra Info. */
  1547. {
  1548.  register LONG rowsize,width;
  1549.  register UBYTE *i_ptr;
  1550.  register LONG exitflag;
  1551.  register ULONG  type,r_flag,b_cnt,g_cnt,r_cnt; 
  1552.  register ULONG b,g,r;
  1553.  register ULONG offset,dmask,depth;
  1554.  register UBYTE data;
  1555.  LONG changed,xor_flag;
  1556.  LONG tmp,minx,miny,maxx,maxy;
  1557.  LONG kludge_j;
  1558.  /* this kludge is because animations with width less than 320 are considered
  1559.   * centered in the middle of a 320 screen. Does this happen with
  1560.   * animations greater than lores overscan(374) and less than hi-res(640)????
  1561.   */
  1562.  
  1563.  if (imagex >= 320) kludge_j = 0;
  1564.  else kludge_j = (320-imagex)/2;
  1565.  
  1566.  maxx = maxy = 0; minx = imagex; miny = imagey;
  1567.  
  1568.  changed = xor_flag = 0;
  1569.  width = imagex;
  1570.  rowsize = width / 8;
  1571.  exitflag = 0;
  1572.  while(!exitflag)
  1573.  {
  1574.   /* read compression type and reversible_flag(xor data not just set) 
  1575.    */
  1576.   type   = (*delta++) << 8; type   |= (*delta++);
  1577.  
  1578.   if (type != 0 )
  1579.   {
  1580.     r_flag = (*delta++) << 8; r_flag |= (*delta++);
  1581.   }
  1582.   else r_flag = 0; /* Might possibly have to read it anyways */
  1583.   /* switch on compression type */
  1584.   switch(type)
  1585.   {
  1586.    case 0: exitflag = 1; break; /* end of list */
  1587.    case 1:
  1588.       /* Get byte count and group count 
  1589.        */
  1590.       xor_flag |= r_flag;
  1591.       b_cnt = (*delta++) << 8; b_cnt |= (*delta++);
  1592.       g_cnt = (*delta++) << 8; g_cnt |= (*delta++);
  1593.       
  1594.       /* Loop thru groups
  1595.        */
  1596.       for(g=0; g<g_cnt; g++)
  1597.       {
  1598.     ULONG odd_flag;
  1599.         offset = (*delta++) << 8; offset |= (*delta++);
  1600.  
  1601.         offset <<= 3; /* counts bytes */
  1602.         if (kludge_j) 
  1603.              offset = ((offset/320) * imagex) + (offset%320) - kludge_j;
  1604.  
  1605.         i_ptr = (UBYTE *)(image + offset);
  1606.  
  1607.         tmp = offset%imagex; if (tmp<minx) minx=tmp;
  1608.         tmp += 8;            if (tmp>maxx) maxx=tmp;
  1609.         tmp = offset/imagex; if (tmp<miny) miny=tmp;
  1610.         tmp += b_cnt;        if (tmp>maxy) maxy=tmp;
  1611.        
  1612.         odd_flag = (b_cnt * imaged) & 0x01;
  1613.         /* Loop thru byte count 
  1614.          */
  1615.         for(b=0; b < b_cnt; b++)
  1616.         {
  1617.           dmask = 1;
  1618.           for(depth=0;depth<imaged;depth++) /* loop thru planes */
  1619.           {
  1620.             data = *delta++;
  1621.             changed |= data;          /* CHECKFORZERO change */
  1622.             IFF_Byte_Mod(i_ptr,data,dmask,r_flag);
  1623.             dmask <<= 1;
  1624.           } /* end of depth loop */
  1625.           i_ptr += width; /* direction is vertical */
  1626.         } /* end of byte loop */
  1627.         if (odd_flag) delta++; /* pad to short */
  1628.       } /* end of group loop */
  1629.       break;
  1630.    case 2:
  1631.       /* Read row count, byte count and group count 
  1632.        */
  1633.       xor_flag |= r_flag;
  1634.       r_cnt = (*delta++) << 8; r_cnt |= (*delta++);
  1635.       b_cnt = (*delta++) << 8; b_cnt |= (*delta++);
  1636.       g_cnt = (*delta++) << 8; g_cnt |= (*delta++);
  1637.       
  1638.       /* Loop thru groups
  1639.        */
  1640.       for(g=0; g < g_cnt; g++)
  1641.       { ULONG odd_flag;
  1642.         offset = (*delta++) << 8; offset |= (*delta++);
  1643.         offset <<= 3; /* counts bytes */
  1644.         if (kludge_j) 
  1645.              offset = ((offset/320) * imagex) + (offset%320) - kludge_j;
  1646.  
  1647.         tmp = offset%imagex;     if (tmp<minx) minx=tmp;
  1648.         tmp += b_cnt * 8;        if (tmp>maxx) maxx=tmp;
  1649.         tmp = offset/imagex;     if (tmp<miny) miny=tmp;
  1650.         tmp += r_cnt;            if (tmp>maxy) maxy=tmp;
  1651.        
  1652.         odd_flag = (r_cnt * b_cnt * imaged) & 0x01;
  1653.         /* Loop thru rows of group
  1654.          */
  1655.         for(r=0; r < r_cnt; r++)
  1656.         {
  1657.           dmask = 1;
  1658.           for(depth=0;depth<imaged;depth++) /* loop thru planes */
  1659.           {
  1660.             i_ptr = (UBYTE *)(image + offset + (r * width));
  1661.             for(b=0; b < b_cnt; b++) /* loop thru byte count */
  1662.             {
  1663.               data = *delta++;
  1664.               changed |= data;        /* CHECKFORZERO */
  1665.            
  1666.               IFF_Byte_Mod(i_ptr,data,dmask,r_flag);
  1667.               i_ptr += 8;        /* data is horizontal */
  1668.             } /* end of byte loop */
  1669.             dmask <<= 1;
  1670.           } /* end of depth loop */
  1671.         } /* end of row loop */
  1672.         if (odd_flag) delta++; /* pad to short */
  1673.       } /* end of group loop */
  1674.       break;
  1675.    default: /* don't know this one yet */
  1676.             fprintf(stderr,"Unknown J-type %x\n",type);
  1677.             type = 0;      /* force an exit */
  1678.             exitflag = 1;
  1679.             break;
  1680.   } /* end of type switch */
  1681.  } /* end of while loop */
  1682.  
  1683.  /* if changed is zero then this Delta didn't change the image at all */ 
  1684.  if (changed==0)
  1685.  {
  1686.    *xs = *ys = *xe = *ye = 0;
  1687.    return(ACT_DLTA_NOP);
  1688.  }
  1689.  if (xa_optimize_flag == TRUE)
  1690.  {
  1691.    *xs = minx; *ys = miny;
  1692.    *xe = maxx; *ye = maxy;
  1693.  
  1694.    if (*xs >= imagex) *xs = 0;
  1695.    if (*ys >= imagey) *ys = 0;
  1696.    if (*xe <= 0)      *xe = imagex;
  1697.    if (*ye <= 0)      *ye = imagey;
  1698.    DEBUG_LEVEL2 fprintf(stderr,"xypos=<%ld,%ld> xysize=<%ld %ld>\n",
  1699.         *xs,*ys,*xe,*ye );
  1700.  }
  1701.  else
  1702.  {
  1703.    *xs = 0; *ys = 0;
  1704.    *xe = imagex; *ye = imagey;
  1705.  }
  1706.  if (xor_flag) return(ACT_DLTA_XOR);
  1707.  return(ACT_DLTA_NORM);
  1708. } /* end of IFF_DeltaJ routine */
  1709.  
  1710. /* 
  1711.  *  Decode IFF type l anims
  1712.  */
  1713. ULONG
  1714. IFF_Delta_l(image,delta,dsize,chdr,map,map_flag,imagex,imagey,imaged,
  1715.                         xs,ys,xe,ye,special,vertflag)
  1716. UBYTE *image;        /* Image Buffer. */
  1717. UBYTE *delta;        /* delta data. */
  1718. ULONG dsize;        /* delta size */
  1719. XA_CHDR *chdr;        /* color map info */
  1720. ULONG *map;        /* used if it's going to be remapped. */
  1721. ULONG map_flag;        /* whether or not to use remap_map info. */
  1722. ULONG imagex,imagey;    /* Size of image buffer. */
  1723. ULONG imaged;        /* Depth of Image. (IFF specific) */
  1724. ULONG *xs,*ys;        /* pos of changed area. */
  1725. ULONG *xe,*ye;        /* size of changed area. */
  1726. ULONG special;        /* Special Info. */
  1727. ULONG vertflag;        /* Extra Info. 1 = vertical encoding*/
  1728. {
  1729.  register LONG i,depth,dmask,width;
  1730.  ULONG poff0,poff1;
  1731.  register UBYTE *i_ptr;
  1732.  register UBYTE *optr,*dptr;
  1733.  register SHORT cnt;
  1734.  register USHORT offset,data;
  1735.  
  1736.  *xs = *ys = 0; *xe = imagex; *ye = imagey;
  1737.  i_ptr = image;
  1738.  if (vertflag) width = imagex;
  1739.  else width = 16;
  1740.  dmask = 1;
  1741.  for(depth = 0; depth<imaged; depth++)
  1742.  {
  1743.    i_ptr = image;
  1744.    /*poff = planeoff[depth];*/ /* offset into delt chunk */
  1745.    poff0  = (ULONG)(delta[ 4 * depth    ]) << 24;
  1746.    poff0 |= (ULONG)(delta[ 4 * depth + 1]) << 16;
  1747.    poff0 |= (ULONG)(delta[ 4 * depth + 2]) <<  8;
  1748.    poff0 |= (ULONG)(delta[ 4 * depth + 3]);
  1749.  
  1750.    if (poff0)
  1751.    {
  1752.      poff1  = (ULONG)(delta[ 4 * (depth+8)    ]) << 24;
  1753.      poff1 |= (ULONG)(delta[ 4 * (depth+8) + 1]) << 16;
  1754.      poff1 |= (ULONG)(delta[ 4 * (depth+8) + 2]) <<  8;
  1755.      poff1 |= (ULONG)(delta[ 4 * (depth+8) + 3]);
  1756.  
  1757.      dptr = (UBYTE *)(delta + 2 * poff0); 
  1758.      optr = (UBYTE *)(delta + 2 * poff1); 
  1759.  
  1760.      /* while short *optr != -1 */
  1761.      while( (optr[0] != 0xff) || (optr[1] != 0xff) )
  1762.      {
  1763.        offset = (*optr++) << 8; offset |= (*optr++);
  1764.        cnt    = (*optr++) << 8; cnt    |= (*optr++);
  1765.  
  1766.        if (cnt < 0)  /* cnt negative */
  1767.        {
  1768.          i_ptr = image + 16 * (ULONG)(offset);
  1769.          cnt = -cnt;
  1770.          data = (*dptr++) << 8; data |= (*dptr++);
  1771.          for(i=0; i < (ULONG)cnt; i++)
  1772.          {
  1773.            IFF_Short_Mod(i_ptr,data,dmask,0);
  1774.            i_ptr += width;
  1775.          }
  1776.        }  /* end of neg */
  1777.        else/* cnt pos then */
  1778.        {
  1779.          i_ptr = image + 16 * (ULONG)(offset);
  1780.          for(i=0; i < (ULONG)cnt; i++)
  1781.          {
  1782.            data = (*dptr++) << 8; data |= (*dptr++);
  1783.            IFF_Short_Mod(i_ptr,data,dmask,0);
  1784.            i_ptr += width;
  1785.          }
  1786.        } /* end of pos */
  1787.      } /* end of delta for this plane */
  1788.    } /* plane has changed data */
  1789.    dmask <<= 1;
  1790.  } /* end of d */
  1791.  return(ACT_DLTA_NORM);
  1792. }
  1793.  
  1794. void
  1795. IFF_Setup_HMAP(act,hmap,cmap,bits)
  1796. XA_ACTION *act;
  1797. ColorReg *hmap,*cmap;
  1798. ULONG bits;
  1799. {
  1800.   ColorReg *hptr;
  1801.   ULONG i,size,shift;
  1802.  
  1803.   if (bits == 8) {size = XA_HMAP8_SIZE; shift = 2;}
  1804.   else {size = XA_HMAP6_SIZE; shift = 4;}
  1805.   
  1806.   act->data = (UBYTE *) malloc(size * sizeof(ColorReg) );
  1807.   if (act->data == 0) IFF_TheEnd1("IFF_Setup_HMAP: malloc failed\n");
  1808.   hptr = (ColorReg *) act->data;
  1809.   for(i=0; i < size; i++) 
  1810.   {
  1811.     hptr[i].red   = hmap[i].red   = cmap[i].red   >> shift;
  1812.     hptr[i].green = hmap[i].green = cmap[i].green >> shift;
  1813.     hptr[i].blue  = hmap[i].blue  = cmap[i].blue  >> shift;
  1814.   }
  1815. }
  1816.  
  1817.  
  1818. IFF_DLTA_HDR iff_dlta[2];
  1819.  
  1820. void
  1821. IFF_Init_DLTA_HDR(max_x,max_y)
  1822. ULONG max_x,max_y;
  1823. {
  1824.   iff_dlta[0].minx = iff_dlta[1].minx = 0;
  1825.   iff_dlta[0].miny = iff_dlta[1].miny = 0;
  1826.   iff_dlta[0].maxx = iff_dlta[1].maxx = max_x;
  1827.   iff_dlta[0].maxy = iff_dlta[1].maxy = max_y;
  1828. }
  1829.  
  1830. void
  1831. IFF_Update_DLTA_HDR(min_x,min_y,max_x,max_y)
  1832. LONG *min_x,*min_y,*max_x,*max_y;
  1833. {
  1834.   register LONG tmin_x,tmin_y,tmax_x,tmax_y;
  1835.  
  1836.  /* This mess keeps track of the largest rectangle needed to
  1837.   * display all changes. Since things are double buffered, the
  1838.   * min/maxes of the corners of the current and previous two
  1839.   * images are taken. If the animation is in single step mode
  1840.   * it's best to display the entire image.
  1841.   */
  1842.   /* Special condition if max_x is 0, then return previous largest values*/
  1843.  
  1844.   if (max_x)
  1845.   {
  1846.     tmin_x = *min_x;
  1847.     tmin_y = *min_y;
  1848.     tmax_x = *max_x;
  1849.     tmax_y = *max_y;
  1850.     iff_dlta[0].minx = XA_MIN(iff_dlta[0].minx, tmin_x);
  1851.     iff_dlta[0].miny = XA_MIN(iff_dlta[0].miny, tmin_y);
  1852.     iff_dlta[0].maxx = XA_MAX(iff_dlta[0].maxx, tmax_x);
  1853.     iff_dlta[0].maxy = XA_MAX(iff_dlta[0].maxy, tmax_y);
  1854.     *min_x = XA_MIN(iff_dlta[1].minx, iff_dlta[0].minx);
  1855.     *min_y = XA_MIN(iff_dlta[1].miny, iff_dlta[0].miny);
  1856.     *max_x = XA_MAX(iff_dlta[1].maxx, iff_dlta[0].maxx);
  1857.     *max_y = XA_MAX(iff_dlta[1].maxy, iff_dlta[0].maxy);
  1858.     /* Throw out oldest rectangle and store current.  */
  1859.     iff_dlta[1].minx = iff_dlta[0].minx;
  1860.     iff_dlta[1].miny = iff_dlta[0].miny;
  1861.     iff_dlta[1].maxx = iff_dlta[0].maxx;
  1862.     iff_dlta[1].maxy = iff_dlta[0].maxy;
  1863.     iff_dlta[0].minx = tmin_x;
  1864.     iff_dlta[0].miny = tmin_y;
  1865.     iff_dlta[0].maxx = tmax_x;
  1866.     iff_dlta[0].maxy = tmax_y;
  1867.   }
  1868.   else
  1869.   {
  1870.     *min_x = XA_MIN(iff_dlta[1].minx, iff_dlta[0].minx);
  1871.     *min_y = XA_MIN(iff_dlta[1].miny, iff_dlta[0].miny);
  1872.     *max_x = XA_MAX(iff_dlta[1].maxx, iff_dlta[0].maxx);
  1873.     *max_y = XA_MAX(iff_dlta[1].maxy, iff_dlta[0].maxy);
  1874.   }
  1875. }
  1876.  
  1877. void
  1878. IFF_Read_BMHD(fin,bmhd)
  1879. FILE *fin;
  1880. Bit_Map_Header *bmhd;
  1881. {
  1882.   /* read Bit_Map_Header into bmhd */
  1883.   /* read so as to avoid endian problems */
  1884.   bmhd->width              = UTIL_Get_MSB_Short(fin);
  1885.   bmhd->height             = UTIL_Get_MSB_Short(fin);
  1886.   bmhd->x                  = UTIL_Get_MSB_Short(fin);
  1887.   bmhd->y                  = UTIL_Get_MSB_Short(fin);
  1888.   bmhd->depth              = fgetc(fin);
  1889.   bmhd->masking            = fgetc(fin);
  1890.   bmhd->compression        = fgetc(fin);
  1891.   bmhd->pad1               = fgetc(fin);
  1892.   bmhd->transparentColor   = UTIL_Get_MSB_Short(fin);
  1893.   bmhd->xAspect            = fgetc(fin);
  1894.   bmhd->yAspect            = fgetc(fin);
  1895.   bmhd->pageWidth          = UTIL_Get_MSB_Short(fin);
  1896.   bmhd->pageHeight         = UTIL_Get_MSB_Short(fin);
  1897.  
  1898. void
  1899. IFF_Read_ANHD(fin,anhd,chunk_size)
  1900. FILE *fin;
  1901. Anim_Header *anhd;
  1902. ULONG chunk_size;
  1903. {
  1904.   ULONG i;
  1905.   anhd->op        = fgetc(fin);
  1906.   anhd->mask        = fgetc(fin);
  1907.   anhd->w        = UTIL_Get_MSB_Short(fin);
  1908.   anhd->h        = UTIL_Get_MSB_Short(fin);
  1909.   anhd->x        = UTIL_Get_MSB_Short(fin);
  1910.   anhd->y        = UTIL_Get_MSB_Short(fin);
  1911.   anhd->abstime        = UTIL_Get_MSB_Long(fin);
  1912.   anhd->reltime        = UTIL_Get_MSB_Long(fin);
  1913.   anhd->interleave    = fgetc(fin);
  1914.   anhd->pad0        = fgetc(fin);
  1915.   anhd->bits        = UTIL_Get_MSB_Long(fin);
  1916.   fread((BYTE *)(anhd->pad),1,16,fin); /* read pad */
  1917.   i = Anim_Header_SIZE;
  1918.   while(i < chunk_size) {fgetc(fin); i++;}
  1919. }
  1920.  
  1921. void
  1922. IFF_Read_ANSQ(fin,chunk_size)
  1923. FILE *fin;
  1924. ULONG chunk_size;
  1925. {
  1926.   ULONG i;
  1927.   UBYTE *p;  /* data is actually big endian USHORT */
  1928.   BYTE *garb;
  1929.  
  1930.   iff_ansq_cnt = chunk_size / 4;
  1931.   iff_ansq_cnt++; /* adding dlta 0 up front */
  1932.   DEBUG_LEVEL2 fprintf(stderr,"    ansq_cnt=%ld dlta_cnt=%ld\n",
  1933.                         iff_ansq_cnt,iff_dlta_cnt);
  1934.   /* allocate space for ansq variables
  1935.   */
  1936.   iff_ansq = (IFF_ANSQ *)malloc( iff_ansq_cnt * sizeof(IFF_ANSQ));
  1937.   if (iff_ansq == NULL) IFF_TheEnd1("IFF_Read_ANSQ: malloc err");
  1938.   if (xa_verbose) fprintf(stderr,"     frames=%ld dlts=%d comp=%ld\n",
  1939.             iff_ansq_cnt,iff_dlta_cnt,iff_dlta_compression);
  1940.   garb = (BYTE *)malloc(chunk_size);
  1941.   if (garb==0)
  1942.   {
  1943.     fprintf(stderr,"ansq malloc not enough\n");
  1944.     IFF_TheEnd();
  1945.   }
  1946.   fread(garb,chunk_size,1,fin);
  1947.   p = (UBYTE *)(garb);
  1948.   /* first delta is only used once and doesn't appear in
  1949.   * the ANSQ
  1950.   */
  1951.   iff_ansq[0].dnum  = 0;
  1952.   iff_ansq[0].time  = 1;
  1953.   for(i=1; i<iff_ansq_cnt; i++)
  1954.   {
  1955.     /* this is delta to apply */
  1956.     iff_ansq[i].dnum  = (ULONG)(*p++)<<8;
  1957.     iff_ansq[i].dnum |= (ULONG)(*p++);
  1958.     /* this is jiffy count or if 0xffff then a goto */
  1959.     iff_ansq[i].time  = (ULONG)(*p++)<<8;
  1960.     iff_ansq[i].time |= (ULONG)(*p++);
  1961.     iff_ansq[i].frame = 0;
  1962.     DEBUG_LEVEL2
  1963.     fprintf(stderr,"<%ld %ld> ",iff_ansq[i].dnum, iff_ansq[i].time);
  1964.   }
  1965.   FREE(garb,0x100C); garb=0;
  1966. }
  1967.  
  1968. /*
  1969.  * Function to register any CRNGs that occur before CMAP in IFF file
  1970.  */
  1971. void
  1972. IFF_Register_CRNGs(anim_hdr,chdr)
  1973. XA_ANIM_HDR *anim_hdr;
  1974. XA_CHDR *chdr;
  1975. {
  1976.   XA_ACTION *act;
  1977.  
  1978.   act = (XA_ACTION *)anim_hdr->acts;
  1979.  
  1980.   while(act)
  1981.   {
  1982.     if ( (act->type == ACT_CYCLE) && (act->chdr == 0) )
  1983.              ACT_Add_CHDR_To_Action(act,chdr);
  1984.     act = act->next;
  1985.   }
  1986. }
  1987.  
  1988.  
  1989. void
  1990. IFF_Read_CRNG(anim_hdr,fin,chunk_size,crng_flag)
  1991. XA_ANIM_HDR *anim_hdr;
  1992. FILE *fin;
  1993. ULONG chunk_size;
  1994. ULONG *crng_flag;
  1995. {
  1996. /* CRNG_HDR
  1997.  * word pad1,rate,active;
  1998.  * byte low,high;
  1999.  */
  2000.  
  2001.   /* is the chunk the correct size ?
  2002.   */
  2003.   if (chunk_size == IFF_CRNG_HDR_SIZE)
  2004.   {
  2005.     XA_ACTION *act;
  2006.     ULONG rate,active,low,high,csize;
  2007.     ACT_CYCLE_HDR *act_cycle;
  2008.  
  2009.     /* read CRNG chunk */
  2010.     rate   = UTIL_Get_MSB_UShort(fin);  /* throw away pad1 */
  2011.     rate   = UTIL_Get_MSB_UShort(fin);
  2012.     active = UTIL_Get_MSB_UShort(fin);
  2013.     low    = fgetc(fin);
  2014.     high   = fgetc(fin);
  2015.     /* make it an action only if its valid
  2016.     */
  2017.     if (   (active & IFF_CRNG_ACTIVE) && (low < high) 
  2018.     && (rate > IFF_CRNG_DPII_KLUDGE) && (iff_allow_cycling == TRUE) )
  2019.     {
  2020.       ULONG i,*i_ptr;
  2021.  
  2022.       csize = high - low + 1;
  2023.       act_cycle = (ACT_CYCLE_HDR *)
  2024.     malloc( sizeof(ACT_CYCLE_HDR) + (csize * sizeof(ULONG)) );
  2025.       if (act_cycle == 0) IFF_TheEnd1("IFF_Read_CRNG: malloc failed");
  2026.  
  2027.       act_cycle->size = csize;
  2028.       act_cycle->curpos = 0;
  2029.       act_cycle->rate  = (ULONG)(IFF_CRNG_INTERVAL/rate);
  2030.       act_cycle->flags = ACT_CYCLE_ACTIVE;
  2031.       if (active & IFF_CRNG_REVERSE) act_cycle->flags |= ACT_CYCLE_REVERSE;
  2032.  
  2033.       i_ptr = (ULONG *)act_cycle->data;
  2034.       for(i=0; i<csize; i++) 
  2035.       {
  2036.         i_ptr[i] = low + i + iff_or_mask;
  2037.       }
  2038.  
  2039.       *crng_flag = *crng_flag + 1;
  2040.       act = ACT_Get_Action(anim_hdr,ACT_CYCLE);
  2041.       IFF_Add_Frame(0,act);
  2042.       act->data = (UBYTE *) act_cycle;
  2043.     /* register it now if iff_chdr valid, else wait to later */
  2044.       if (iff_chdr) ACT_Add_CHDR_To_Action(act,iff_chdr);
  2045.     }
  2046.     else DEBUG_LEVEL2 fprintf(stderr,"IFF_CRNG not used\n");
  2047.   }
  2048.   else
  2049.   {
  2050.     IFF_Read_Garb(fin,chunk_size);
  2051.     fprintf(stderr,"IFF_CRNG chunksize mismatch %ld\n",chunk_size);
  2052.   }
  2053. }
  2054.  
  2055.  
  2056. void
  2057. IFF_Read_CMAP_0(cmap,size,fin)
  2058. ColorReg *cmap;
  2059. ULONG size;
  2060. FILE *fin;
  2061. {
  2062.   ULONG i;
  2063.   for(i=0; i < size; i++)
  2064.   {
  2065.     cmap[i].red   = fgetc(fin);
  2066.     cmap[i].green = fgetc(fin);
  2067.     cmap[i].blue  = fgetc(fin);
  2068.   }
  2069. }
  2070.  
  2071. void
  2072. IFF_Read_CMAP_1(cmap,size,fin)
  2073. ColorReg *cmap;
  2074. ULONG size;
  2075. FILE *fin;
  2076. {
  2077.   ULONG i;
  2078.   for(i=0; i < size; i++)
  2079.   {
  2080.     ULONG d;
  2081.     d = fgetc(fin);
  2082.     cmap[i].red   = (d & 0x0f) << 4;
  2083.     d = fgetc(fin);
  2084.     cmap[i].green = (d & 0xf0);
  2085.     cmap[i].blue  = (d & 0x0f) << 4;
  2086.   }
  2087. }
  2088.  
  2089.  
  2090. void IFF_Buffer_HAM6(out,in,chdr,h_cmap,xosize,yosize,xip,yip,xisize,d_flag)
  2091. UBYTE *out;        /* output image (size of section) */
  2092. UBYTE *in;        /* input image */
  2093. XA_CHDR *chdr;        /* color header to map to */
  2094. ColorReg *h_cmap;    /* ham color map */
  2095. ULONG xosize,yosize;    /* size of section in input buffer */
  2096. ULONG xip,yip;        /* pos of section in input buffer */
  2097. ULONG xisize;        /* x size of input buffer */
  2098. ULONG d_flag;        /* map_flag */
  2099. {
  2100.   XA_CHDR *the_chdr;
  2101.   ULONG new_cmap_flag,*the_map,psize;
  2102.   register ULONG y,xend,the_moff,coff;
  2103.   USHORT g_adj[16];
  2104.  
  2105.   if (x11_display_type & XA_X11_TRUE) 
  2106.     for(y=0;y<16;y++) g_adj[y] = xa_gamma_adj[ (17 * y) ];
  2107.  
  2108.   the_map = chdr->map;
  2109.   coff = chdr->coff;
  2110.   if (chdr->new_chdr == 0) { the_chdr = chdr; new_cmap_flag = 0; }
  2111.   else { the_chdr = chdr->new_chdr; new_cmap_flag = 1; }
  2112.   the_moff = the_chdr->moff;
  2113.   if (x11_display_type & XA_X11_TRUE) d_flag = TRUE;
  2114.   if (d_flag==TRUE) psize = x11_bytes_pixel;
  2115.   else psize = 1;
  2116.  
  2117.   DEBUG_LEVEL1 fprintf(stderr,"ham_cmap: = %lx\n",(ULONG)h_cmap);
  2118.  
  2119.   if (xa_ham_map == 0)
  2120.   {
  2121.      xa_ham_map_size = XA_HAM6_CACHE_SIZE;
  2122.      xa_ham_map = (ULONG *)malloc( xa_ham_map_size * sizeof(ULONG) );
  2123.      if (xa_ham_map == 0) IFF_TheEnd1("IFF_Buffer_HAM6: h_map malloc err");
  2124.   }
  2125.   if ((the_chdr != xa_ham_chdr) || (xa_ham_init != 6))
  2126.   {
  2127.     register ULONG i;
  2128.     DEBUG_LEVEL1 fprintf(stderr,"xa_ham_map: old = %lx new = %lx\n",
  2129.                     (ULONG)xa_ham_chdr,(ULONG)the_chdr);
  2130.     for(i=0; i<XA_HAM6_CACHE_SIZE; i++) xa_ham_map[i] = XA_HAM_MAP_INVALID;
  2131.     xa_ham_chdr = the_chdr; xa_ham_init = 6;
  2132.   }
  2133.  
  2134.   xend = xip + xosize; if (xend > xisize) xend = xisize;
  2135.   for (y=yip; y < (yip + yosize); y++)
  2136.   {
  2137.     register ULONG x;
  2138.     register UBYTE *i_ptr = (UBYTE *)( in + y * xisize );
  2139.     register UBYTE *o_ptr = (UBYTE *)( out + (y-yip)*xosize * psize );
  2140.     register ULONG pred,pgrn,pblu,data;
  2141.     pred = pgrn = pblu = 0;
  2142.     for (x=0; x<xend; x++)
  2143.     {
  2144.       data = (USHORT )(*i_ptr++);
  2145.       switch(data & 0x30)
  2146.       {
  2147.         case 0x00: /* use color register given by low */
  2148.           { register USHORT low = data & 0x0f;
  2149.             pred = h_cmap[low].red;
  2150.             pgrn = h_cmap[low].green;
  2151.             pblu = h_cmap[low].blue;
  2152.           } break;
  2153.         case 0x10: pblu = data & 0x0f; break; /* change blue */
  2154.         case 0x20: pred = data & 0x0f; break; /* change red */
  2155.         case 0x30: pgrn = data & 0x0f; break; /* change green */
  2156.       }
  2157.       if ( (x >= xip) && (x < xend) )
  2158.       {
  2159.         register ULONG t_color;
  2160.         register USHORT indx = (pred << 8) | (pgrn << 4) | pblu;
  2161.  
  2162.         if ( (t_color = xa_ham_map[indx]) == XA_HAM_MAP_INVALID) 
  2163.         {
  2164.           if (x11_display_type & XA_X11_TRUE) t_color = 
  2165.         X11_Get_True_Color( g_adj[pred],g_adj[pgrn],g_adj[pblu],16);
  2166.       else /* don't gamma because chdr already adjusted */
  2167.       {
  2168.             if (cmap_true_to_332 == TRUE)
  2169.          t_color = CMAP_GET_332(pred,pgrn,pblu,CMAP_SCALE4);
  2170.         else t_color = CMAP_GET_GRAY(pred,pgrn,pblu,CMAP_SCALE9);
  2171.             if (new_cmap_flag) t_color = the_map[t_color - coff] + the_moff;
  2172.       }
  2173.           xa_ham_map[indx] = t_color;
  2174.     }
  2175.  
  2176.     if (d_flag)
  2177.     {
  2178.           if (x11_bytes_pixel == 4)
  2179.              { ULONG *ulp = (ULONG *)o_ptr; *ulp = t_color; o_ptr += 4; }
  2180.           else if (x11_bytes_pixel == 2) { USHORT *usp = (USHORT *)o_ptr;
  2181.              *usp = (USHORT)(t_color); o_ptr += 2; }
  2182.           else *o_ptr++ = (UBYTE)t_color;
  2183.     } else *o_ptr++ = (UBYTE)t_color;
  2184.       } /* end of output */
  2185.     } /* end of x */
  2186.   } /* end of y */
  2187. }
  2188.  
  2189.  
  2190. void IFF_Buffer_HAM8(out,in,chdr,h_cmap,xosize,yosize,xip,yip,xisize,d_flag)
  2191. UBYTE *out;        /* output image (size of section) */
  2192. UBYTE *in;        /* input image */
  2193. XA_CHDR *chdr;        /* color header to map to */
  2194. ColorReg *h_cmap;    /* ham color map */
  2195. ULONG xosize,yosize;    /* size of section in input buffer */
  2196. ULONG xip,yip;        /* pos of section in input buffer */
  2197. ULONG xisize;        /* x size of input buffer */
  2198. ULONG d_flag;        /* map_flag */
  2199. {
  2200.   XA_CHDR *the_chdr;
  2201.   ULONG new_cmap_flag,*the_map,psize;
  2202.   register ULONG y,xend,the_moff,coff;
  2203.   USHORT g_adj[64];
  2204.  
  2205.   if (x11_display_type & XA_X11_TRUE) 
  2206.     for(y=0;y<64;y++) g_adj[y] = xa_gamma_adj[ ((65 * y) >> 4) ];
  2207.   the_map = chdr->map;
  2208.   coff = chdr->coff;
  2209.   if (chdr->new_chdr == 0) { the_chdr = chdr; new_cmap_flag = 0; }
  2210.   else { the_chdr = chdr->new_chdr; new_cmap_flag = 1; }
  2211.   the_moff = chdr->moff;
  2212.   if (x11_display_type & XA_X11_TRUE) d_flag = TRUE;
  2213.   if (d_flag==TRUE) psize = x11_bytes_pixel;
  2214.   else psize = 1;
  2215.  
  2216.   if (xa_ham_map_size != XA_HAM8_CACHE_SIZE)
  2217.   {
  2218.     if (xa_ham_map == 0)
  2219.     {
  2220.          xa_ham_map_size = XA_HAM8_CACHE_SIZE;
  2221.          xa_ham_map = (ULONG *)malloc( xa_ham_map_size * sizeof(ULONG) );
  2222.          if (xa_ham_map == 0) IFF_TheEnd1("IFF_Buffer_HAM8: h_map malloc err");
  2223.     }
  2224.     else
  2225.     {
  2226.       ULONG *tmp;
  2227.       xa_ham_map_size = XA_HAM8_CACHE_SIZE;
  2228.       tmp = (ULONG *) realloc(xa_ham_map,xa_ham_map_size * sizeof(ULONG));
  2229.       if (tmp == 0) IFF_TheEnd1("IFF_Buffer_HAM8: h_map malloc err");
  2230.       xa_ham_map = tmp;
  2231.     }
  2232.     xa_ham_chdr = 0;
  2233.   }
  2234.   if ( (the_chdr != xa_ham_chdr) || (xa_ham_init != 8))
  2235.   {
  2236.     register ULONG i;
  2237.     DEBUG_LEVEL1 fprintf(stderr,"xa_ham8_map: old = %lx new = %lx\n",
  2238.                     (ULONG)xa_ham_chdr,(ULONG)the_chdr);
  2239.     for(i=0; i<XA_HAM8_CACHE_SIZE; i++) xa_ham_map[i] = XA_HAM_MAP_INVALID;
  2240.     xa_ham_chdr = the_chdr; xa_ham_init = 8;
  2241.   }
  2242.  
  2243.   xend = xip + xosize; if (xend > xisize) xend = xisize;
  2244.   for (y=yip; y < (yip + yosize); y++)
  2245.   {
  2246.     register ULONG x;
  2247.     register UBYTE *i_ptr = (UBYTE *)( in + y * xisize );
  2248.     register UBYTE *o_ptr = (UBYTE *)( out + (y-yip) *xosize * psize);
  2249.     register ULONG pred,pgrn,pblu,data;
  2250.  
  2251.     pred = pgrn = pblu = 0;
  2252.     for (x=0; x<xend; x++)
  2253.     {
  2254.       data = (ULONG )(*i_ptr++);
  2255.       switch(data & 0xc0)
  2256.       {
  2257.         case 0x00: /* use color register given by low */
  2258.           { register ULONG low = data & 0x3f;
  2259.             pred  = h_cmap[low].red;
  2260.             pgrn  = h_cmap[low].green;
  2261.             pblu  = h_cmap[low].blue;
  2262.           } break;
  2263.         case 0x40: pblu = data & 0x3f; break; /* change blue */
  2264.         case 0x80: pred = data & 0x3f; break; /* change red */
  2265.         case 0xc0: pgrn = data & 0x3f; break; /* change green */
  2266.       }
  2267.       if ( (x >= xip) && (x < xend) )
  2268.       {
  2269.         register ULONG t_color;
  2270.         register ULONG indx = (pred << 12) | (pgrn << 6) | pblu;
  2271.  
  2272.         if ( (t_color = xa_ham_map[indx]) == XA_HAM_MAP_INVALID) 
  2273.         {
  2274.           if (x11_display_type & XA_X11_TRUE) t_color = 
  2275.         X11_Get_True_Color( g_adj[pred],g_adj[pgrn],g_adj[pblu],16);
  2276.       else /* no gamma here because it's already in cmap */
  2277.       {
  2278.             if (cmap_true_to_332 == TRUE)
  2279.          t_color = CMAP_GET_332(pred,pgrn,pblu,CMAP_SCALE6);
  2280.         else t_color = CMAP_GET_GRAY(pred,pgrn,pblu,CMAP_SCALE11);
  2281.             if (new_cmap_flag) t_color = the_map[t_color - coff] + the_moff;
  2282.       }
  2283.           xa_ham_map[indx] = t_color;
  2284.     }
  2285.     if (d_flag)
  2286.     {
  2287.           if (x11_bytes_pixel == 4)
  2288.              { ULONG *ulp = (ULONG *)o_ptr; *ulp = t_color; o_ptr += 4; }
  2289.           else if (x11_bytes_pixel == 2) { USHORT *usp = (USHORT *)o_ptr;
  2290.                          *usp = (USHORT)(t_color); o_ptr += 2; }
  2291.           else *o_ptr++ = (UBYTE)t_color;
  2292.     } else *o_ptr++ = (UBYTE)t_color;
  2293.       } /* end of output */
  2294.     } /* end of x */
  2295.   } /* end of y */
  2296. }
  2297.  
  2298. void
  2299. IFF_Shift_CMAP(cmap,csize)
  2300. ColorReg *cmap;
  2301. ULONG csize;
  2302. {
  2303.   ULONG i;
  2304.   for(i=0;i<csize;i++)
  2305.   {
  2306.     cmap[i].red   >>= 4;
  2307.     cmap[i].green >>= 4;
  2308.     cmap[i].blue  >>= 4;
  2309.   }
  2310. }
  2311.  
  2312. ULONG
  2313. IFF_Delta_7(image,delta,dsize,chdr,map,map_flag,imagex,imagey,imaged,
  2314.                         xs,ys,xe,ye,special,extra)
  2315. UBYTE *image;        /* Image Buffer. */
  2316. UBYTE *delta;        /* delta data. */
  2317. ULONG dsize;        /* delta size */
  2318. XA_CHDR *chdr;        /* color map info */
  2319. ULONG *map;        /* used if it's going to be remapped. */
  2320. ULONG map_flag;        /* whether or not to use remap_map info. */
  2321. ULONG imagex,imagey;    /* Size of image buffer. */
  2322. ULONG imaged;        /* Depth of Image. (IFF specific) */
  2323. ULONG *xs,*ys;        /* pos of changed area. */
  2324. ULONG *xe,*ye;        /* size of changed area. */
  2325. ULONG special;        /* Special Info. */
  2326. ULONG extra;        /* Extra Info. 0 = short encoding, 1 = long encoding*/
  2327. {
  2328.  register LONG col,depth,dmask;
  2329.  register LONG rowsize,width;
  2330.  ULONG poff,doff,col_shift;
  2331.  register UBYTE *i_ptr;
  2332.  register UBYTE *optr,opcnt,op,cnt;
  2333.  UBYTE *d_ptr;
  2334.  LONG miny,minx,maxy,maxx;
  2335.  
  2336.  /* set to opposites for min/max testing */
  2337.  *xs = imagex;
  2338.  *ys = imagey;
  2339.  *xe = 0;
  2340.  *ye = 0;
  2341.  
  2342.  i_ptr = image;
  2343.  width = imagex;
  2344.  col_shift = (extra)?4:5;
  2345.  rowsize = width >> col_shift;
  2346.  dmask = 1;
  2347.  for(depth=0; depth<imaged; depth++)
  2348.  {
  2349.   minx = -1;
  2350.   maxx = -1;
  2351.   
  2352.   i_ptr = image;
  2353.   /* offset into delt chunk */
  2354.   { register ULONG ddepth = depth << 2;
  2355.     poff  = (ULONG)(delta[ ddepth++ ]) << 24;
  2356.     poff |= (ULONG)(delta[ ddepth++ ]) << 16;
  2357.     poff |= (ULONG)(delta[ ddepth++ ]) <<  8;
  2358.     poff |= (ULONG)(delta[ ddepth   ]);
  2359.     ddepth +=29; /* move to data */
  2360.     doff  = (ULONG)(delta[ ddepth++ ]) << 24;
  2361.     doff |= (ULONG)(delta[ ddepth++ ]) << 16;
  2362.     doff |= (ULONG)(delta[ ddepth++ ]) <<  8;
  2363.     doff |= (ULONG)(delta[ ddepth   ]);
  2364.   }
  2365.   if (poff)
  2366.   {
  2367.    optr   = (UBYTE  *)(delta + poff);
  2368.    d_ptr =  (UBYTE *)(delta + doff);
  2369.    
  2370.    for(col=0;col<rowsize;col++)
  2371.    {
  2372.     /* start at top of column */
  2373.     i_ptr = (UBYTE *)(image + (col << col_shift));
  2374.     opcnt = *optr++;  /* get number of ops for this column */
  2375.     
  2376.     miny = -1;
  2377.     maxy = -1;
  2378.  
  2379.     while(opcnt)    /* execute ops */
  2380.     {
  2381.       /* keep track of min and max columns */
  2382.       if (minx == -1) minx = col;
  2383.       maxx = col;
  2384.  
  2385.       op = *optr++;   /* get op */
  2386.      
  2387.       if (extra) /* SHORT Data */
  2388.       {
  2389.         if (op & 0x80)    /* if type uniqe */
  2390.         {
  2391.           if (miny == -1) miny = (ULONG)(i_ptr - image ) / width;
  2392.           cnt = op & 0x7f;         /* get cnt */
  2393.       
  2394.           while(cnt--) /* loop through data */
  2395.           {
  2396.              register ULONG data;
  2397.          data = (*d_ptr++) << 8; data |= *d_ptr++;
  2398.              IFF_Short_Mod(i_ptr,data,dmask,0);
  2399.              i_ptr += width;
  2400.           }
  2401.         } /* end unique */
  2402.         else
  2403.         {
  2404.           if (op == 0)   /* type same */
  2405.           {
  2406.              register USHORT data;
  2407.              if (miny == -1) miny=(ULONG)(i_ptr - image) / width;
  2408.              cnt = *optr++;
  2409.          data = (*d_ptr++) << 8; data |= *d_ptr++;
  2410.  
  2411.              while(cnt--) /* loop through data */
  2412.              { 
  2413.                 IFF_Short_Mod(i_ptr,data,dmask,0);
  2414.                 i_ptr += width;
  2415.              }
  2416.            } /* end same */
  2417.            else
  2418.            {
  2419.               i_ptr += (width * op);  /* type skip */
  2420.            }
  2421.          } /* end of hi bit clear */
  2422.       } /* end of short data */
  2423.       else /* LONG Data */
  2424.       {
  2425.         if (op & 0x80)    /* if type uniqe */
  2426.         {
  2427.           if (miny == -1) miny=(ULONG)( i_ptr - image ) / width;
  2428.           cnt = op & 0x7f;         /* get cnt */
  2429.       
  2430.           while(cnt--) /* loop through data */
  2431.           { register ULONG data;
  2432.         data = (*d_ptr++)<<24; data |= (*d_ptr++)<<16;
  2433.         data |= (*d_ptr++)<<8; data |= *d_ptr++;
  2434.             IFF_Long_Mod(i_ptr,data,dmask,0); i_ptr += width;
  2435.           }
  2436.         } /* end unique */
  2437.         else
  2438.         {
  2439.            if (op == 0) /* type same */
  2440.            { register ULONG data;
  2441.              if (miny == -1) miny=(ULONG)( i_ptr - image ) / width;
  2442.              cnt = *optr++;
  2443.          data = (*d_ptr++)<<24; data |= (*d_ptr++)<<16;
  2444.          data |= (*d_ptr++)<<8; data |= *d_ptr++;
  2445.  
  2446.              while(cnt--) {IFF_Long_Mod(i_ptr,data,dmask,0); i_ptr += width;}
  2447.            } /* end same */
  2448.            else { i_ptr += (width * op);  /* type skip */ }
  2449.          } /* end of hi bit clear */
  2450.        } /* end of long data */
  2451.        opcnt--;
  2452.      } /* end of while opcnt */
  2453.      maxy = (ULONG)( i_ptr - image ) / width;
  2454.      if ( (miny>=0) && (miny < *ys)) *ys = miny;
  2455.      if ( (maxy>=0) && (maxy > *ye)) *ye = maxy;
  2456.     } /* end of column loop */
  2457.    } /* end of valid pointer for this plane */
  2458.    dmask <<= 1;
  2459.    minx <<= col_shift; maxx <<= col_shift;
  2460.    maxx = (extra)?(maxx+15):(maxx+31);
  2461.    if ( (minx>=0) && (minx < *xs)) *xs = minx;
  2462.    if ( (maxx>=0) && (maxx > *xe)) *xe = maxx;
  2463.   } /* end of for depth */
  2464.  
  2465.   if (xa_optimize_flag == TRUE)
  2466.   {
  2467.     if (*xs >= imagex) *xs = 0;
  2468.     if (*ys >= imagey) *ys = 0;
  2469.     if (*xe <= 0)      *xe = imagex;
  2470.     if (*ye <= 0)      *ye = imagey;
  2471.   }
  2472.   else
  2473.   {
  2474.     *xs = 0;      *ys = 0;
  2475.     *xe = imagex; *ye = imagey;
  2476.   }
  2477.   return(ACT_DLTA_NORM);
  2478. } /* end of routine */
  2479.  
  2480. /* POD NOTE: no need to support xorflag yet */
  2481.  
  2482. void IFF_Long_Mod(ptr,data,dmask,xorflag) 
  2483. UBYTE *ptr;
  2484. ULONG data,dmask,xorflag;
  2485. { register UBYTE *_iptr = ptr; 
  2486.   register UBYTE dmaskoff = ~dmask;
  2487.   if (xorflag) TheEnd1("IFF comp7: xorflag not supported yet. Contact Author");
  2488.   if (0x80000000 & data)  *_iptr++  |= dmask; else  *_iptr++  &= dmaskoff;
  2489.   if (0x40000000 & data)  *_iptr++  |= dmask; else  *_iptr++  &= dmaskoff;
  2490.   if (0x20000000 & data)  *_iptr++  |= dmask; else  *_iptr++  &= dmaskoff;
  2491.   if (0x10000000 & data)  *_iptr++  |= dmask; else  *_iptr++  &= dmaskoff;
  2492.   if (0x08000000 & data)  *_iptr++  |= dmask; else  *_iptr++  &= dmaskoff;
  2493.   if (0x04000000 & data)  *_iptr++  |= dmask; else  *_iptr++  &= dmaskoff;
  2494.   if (0x02000000 & data)  *_iptr++  |= dmask; else  *_iptr++  &= dmaskoff;
  2495.   if (0x01000000 & data)  *_iptr++  |= dmask; else  *_iptr++  &= dmaskoff;
  2496.   if (0x00800000 & data)  *_iptr++  |= dmask; else  *_iptr++  &= dmaskoff;
  2497.   if (0x00400000 & data)  *_iptr++  |= dmask; else  *_iptr++  &= dmaskoff;
  2498.   if (0x00200000 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2499.   if (0x00100000 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2500.   if (0x00080000 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2501.   if (0x00040000 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2502.   if (0x00020000 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2503.   if (0x00010000 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2504.   if (0x00008000 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2505.   if (0x00004000 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2506.   if (0x00002000 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2507.   if (0x00001000 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2508.   if (0x00000800 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2509.   if (0x00000400 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2510.   if (0x00000200 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2511.   if (0x00000100 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2512.   if (0x00000080 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2513.   if (0x00000040 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2514.   if (0x00000020 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2515.   if (0x00000010 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2516.   if (0x00000008 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2517.   if (0x00000004 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2518.   if (0x00000002 & data) *_iptr++   |= dmask; else *_iptr++   &= dmaskoff;
  2519.   if (0x00000001 & data) *_iptr     |= dmask; else *_iptr     &= dmaskoff;
  2520. }
  2521.  
  2522.  
  2523.  
  2524.  
  2525. void IFF_HAM6_As_True(out,in,chdr,h_cmap,xosize,yosize,xip,yip,xisize)
  2526. UBYTE *out,*in;
  2527. XA_CHDR **chdr;
  2528. ColorReg *h_cmap;
  2529. ULONG xosize,yosize,xip,yip,xisize;
  2530. {
  2531.   ULONG xend,y;
  2532.   UBYTE *tpic,*optr;
  2533.   USHORT g_adj[16];
  2534.  
  2535.   for(y=0;y<16;y++) g_adj[y] = xa_gamma_adj[ (17 * y) ] >> 8;
  2536.   tpic = (UBYTE *)malloc( 3 * xosize * yosize);
  2537.   if (tpic == 0) TheEnd1("IFF_HAM6_As_True: malloc err\n");
  2538.   optr = tpic;
  2539.   xend = xip + xosize; if (xend > xisize) xend = xisize;
  2540.   for (y=yip; y < (yip + yosize); y++)
  2541.   {
  2542.     register ULONG x;
  2543.     register UBYTE *i_ptr = (UBYTE *)( in + y * xisize );
  2544.     register ULONG pred,pgrn,pblu,data;
  2545.  
  2546.     pred = pgrn = pblu = 0;
  2547.     for (x=0; x<xend; x++)
  2548.     {
  2549.       data = (ULONG )(*i_ptr++);
  2550.       switch( (data & 0x30) )
  2551.       {
  2552.         case 0x00: /* use color register given by low */
  2553.           { register ULONG low;
  2554.             low = data & 0x0f;
  2555.             pred  = g_adj[ h_cmap[low].red   ];
  2556.             pgrn  = g_adj[ h_cmap[low].green ];
  2557.             pblu  = g_adj[ h_cmap[low].blue  ];
  2558.           } break;
  2559.         case 0x10: pblu = g_adj[ (data & 0x0f) ]; break;
  2560.         case 0x20: pred = g_adj[ (data & 0x0f) ]; break;
  2561.         case 0x30: pgrn = g_adj[ (data & 0x0f) ]; break;
  2562.       } 
  2563.       if ( (x >= xip) && (x < xend) )
  2564.       {
  2565.     *optr++ = pred;
  2566.     *optr++ = pgrn;
  2567.     *optr++ = pblu;
  2568.       }
  2569.     } /* end of x */
  2570.   } /* end of y */
  2571.   if (    (cmap_true_to_all == TRUE) 
  2572.       || ((cmap_true_to_1st == TRUE) && (iff_chdr == 0)) )    
  2573.     iff_chdr = CMAP_Create_CHDR_From_True(tpic,8,8,8,xosize,yosize,
  2574.                     iff_cmap,&iff_imagec);
  2575.   else if ( (cmap_true_to_332 == TRUE) && (iff_chdr == 0) )
  2576.     iff_chdr = CMAP_Create_332(iff_cmap,&iff_imagec);
  2577.   else if ( (cmap_true_to_gray == TRUE) && (iff_chdr == 0) )
  2578.     iff_chdr = CMAP_Create_Gray(iff_cmap,&iff_imagec);
  2579.  
  2580.   if (cmap_dither_type == CMAP_DITHER_FLOYD)
  2581.         out = UTIL_RGB_To_FS_Map(out,tpic,iff_chdr,xosize,yosize,TRUE);
  2582.   else
  2583.         out = UTIL_RGB_To_Map(out,tpic,iff_chdr,xosize,yosize,TRUE);
  2584.   *chdr = iff_chdr; 
  2585. }
  2586.  
  2587. void IFF_HAM8_As_True(out,in,chdr,h_cmap,xosize,yosize,xip,yip,xisize)
  2588. UBYTE *out,*in;
  2589. XA_CHDR **chdr;
  2590. ColorReg *h_cmap;
  2591. ULONG xosize,yosize,xip,yip,xisize;
  2592. {
  2593.   ULONG xend,y;
  2594.   UBYTE *tpic,*optr;
  2595.   USHORT g_adj[64];
  2596.  
  2597.   for(y=0;y<64;y++) g_adj[y] = xa_gamma_adj[ ((65 * y) >> 4) ] >> 8;
  2598.   tpic = (UBYTE *)malloc( 3 * xosize * yosize);
  2599.   if (tpic == 0) TheEnd1("IFF_HAM8_As_True: malloc err\n");
  2600.   optr = tpic;
  2601.   xend = xip + xosize; if (xend > xisize) xend = xisize;
  2602.   for (y=yip; y < (yip + yosize); y++)
  2603.   {
  2604.     register ULONG x;
  2605.     register UBYTE *i_ptr = (UBYTE *)( in + y * xisize );
  2606.     register ULONG pred,pgrn,pblu,data;
  2607.  
  2608.     pred = pgrn = pblu = 0;
  2609.     for (x=0; x<xend; x++)
  2610.     {
  2611.       data = (ULONG )(*i_ptr++);
  2612.       switch( (data & 0xc0) )
  2613.       {
  2614.         case 0x00: /* use color register given by low */
  2615.           { register ULONG low = data & 0x3f;
  2616.             pred  = g_adj[ h_cmap[low].red   ];
  2617.             pgrn  = g_adj[ h_cmap[low].green ];
  2618.             pblu  = g_adj[ h_cmap[low].blue  ];
  2619.           } break;
  2620.         case 0x40: pblu = g_adj[ (data & 0x3f) ]; break;
  2621.         case 0x80: pred = g_adj[ (data & 0x3f) ]; break;
  2622.         case 0xc0: pgrn = g_adj[ (data & 0x3f) ]; break;
  2623.       } 
  2624.       if ( (x >= xip) && (x < xend) )
  2625.       {
  2626.     *optr++ = pred;
  2627.     *optr++ = pgrn;
  2628.     *optr++ = pblu;
  2629.       }
  2630.     } /* end of x */
  2631.   } /* end of y */
  2632.   if (    (cmap_true_to_all == TRUE) 
  2633.       || ((cmap_true_to_1st == TRUE) && (iff_chdr == 0)) )    
  2634.     iff_chdr = CMAP_Create_CHDR_From_True(tpic,8,8,8,xosize,yosize,
  2635.                     iff_cmap,&iff_imagec);
  2636.   else if ( (cmap_true_to_332 == TRUE) && (iff_chdr == 0) )
  2637.     iff_chdr = CMAP_Create_332(iff_cmap,&iff_imagec);
  2638.   else if ( (cmap_true_to_gray == TRUE) && (iff_chdr == 0) )
  2639.     iff_chdr = CMAP_Create_Gray(iff_cmap,&iff_imagec);
  2640.  
  2641.   if (cmap_dither_type == CMAP_DITHER_FLOYD)
  2642.         out = UTIL_RGB_To_FS_Map(out,tpic,iff_chdr,xosize,yosize,TRUE);
  2643.   else
  2644.         out = UTIL_RGB_To_Map(out,tpic,iff_chdr,xosize,yosize,TRUE);
  2645.   *chdr = iff_chdr; 
  2646. }
  2647.  
  2648.  
  2649. ULONG
  2650. IFF_Delta_Body(image,delta,dsize,chdr,map,map_flag,imagex,imagey,imaged,
  2651.                         xs,ys,xe,ye,special,extra)
  2652. UBYTE *image;            /* ptr to image out */
  2653. UBYTE *delta;            /* ptr to delta */
  2654. ULONG dsize;            /* delta size */
  2655. XA_CHDR *chdr;            /* color map info */
  2656. ULONG *map;            /* pixel map - use if map_flag */
  2657. ULONG map_flag;            /* ignored */
  2658. ULONG imagex,imagey,imaged;     /* image size and depth */
  2659. ULONG *xs,*ys;            /* pos of changed area */
  2660. ULONG *xe,*ye;            /* size of changed area */
  2661. ULONG special;                     /* reserved */
  2662. ULONG extra;            /* Extra Info. */
  2663. {
  2664.   ULONG image_size = imagex * imagey;
  2665.   memcpy( (char *)image, (char *)delta, image_size);
  2666.   *xs = *ys = 0;  *xe = imagex; *ye = imagey; 
  2667.   return(ACT_DLTA_BODY);
  2668. }
  2669.  
  2670.